{"id":31936458,"url":"https://github.com/stitchng/paystack","last_synced_at":"2025-10-14T07:42:53.205Z","repository":{"id":50130915,"uuid":"163839201","full_name":"stitchng/paystack","owner":"stitchng","description":"A NodeJS Wrapper for Paystack","archived":false,"fork":false,"pushed_at":"2025-03-06T22:56:42.000Z","size":216,"stargazers_count":26,"open_issues_count":2,"forks_count":9,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-10-05T18:18:37.100Z","etag":null,"topics":["api-endpoints","nodejs","payments","paystack","rest-api"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/stitchng.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-01-02T12:37:18.000Z","updated_at":"2025-03-06T22:56:45.000Z","dependencies_parsed_at":"2022-08-02T20:45:22.102Z","dependency_job_id":null,"html_url":"https://github.com/stitchng/paystack","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/stitchng/paystack","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stitchng%2Fpaystack","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stitchng%2Fpaystack/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stitchng%2Fpaystack/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stitchng%2Fpaystack/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/stitchng","download_url":"https://codeload.github.com/stitchng/paystack/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stitchng%2Fpaystack/sbom","scorecard":{"id":853487,"data":{"date":"2025-08-11","repo":{"name":"github.com/stitchng/paystack","commit":"de1c4ba26365d80aacef51c8394c0dc50d3ed27e"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3,"checks":[{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Code-Review","score":0,"reason":"Found 1/11 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 22 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-23T23:10:43.266Z","repository_id":50130915,"created_at":"2025-08-23T23:10:43.266Z","updated_at":"2025-08-23T23:10:43.266Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279018217,"owners_count":26086308,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-14T02:00:06.444Z","response_time":60,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api-endpoints","nodejs","payments","paystack","rest-api"],"created_at":"2025-10-14T07:42:49.292Z","updated_at":"2025-10-14T07:42:53.195Z","avatar_url":"https://github.com/stitchng.png","language":"JavaScript","readme":"# Paystack\n\n[![NPM Version][npm-image]][npm-url]\n[![Build Status][travis-image]][travis-url]\n\nA NodeJS Wrapper for [Paystack](https://www.paystack.com)\n\n## Overview\nThis project provides an easy-to-use object-oriented API to access endpoints delineated at https://developers.paystack.co/reference\n\n## Getting Started\n\n\u003eInstall from the NPM Registry\n\n```bash\n\n    $ npm i --save paystack-node\n\n```\n\n# Usage\n\n```js\n\nlet PayStack = require('paystack-node')\n\nlet APIKEY = 'sk_live_2hWyQ6HW73jS8p1IkXmSWOlE4y9Inhgyd6g5f2R7'\nconst environment = process.env.NODE_ENV\n\nconst paystack = new PayStack(APIKEY, environment)\n\nconst feesCalculator = new PayStack.Fees();\nconst feeCharge = feesCalculator.calculateFor(250000) // 2,500 Naira\n\n/* \n  NOTE: All fields/params that require dates should be set to\n  instances of the `Date()` constructor as they will\n  eventually be turned into the ISO 8601 format (String)\n  using `toJSON()` method for date instances/objects\n*/\n\nconst promise_0 = paystack.getSettlements({\n  from:new Date(\"2017-02-09\"), \n  to:new Date()\n})\n\npromise_0.then(function(response){\n  var data = response.body.data;\n}).catch(function (error){\n  // deal with error\n})\n\n// listBanks\n\ntry {\n  let { body: { status, message, data } } =  await paystack.listBanks({\n    currency: 'NGN'\n  });\n\n  if(status === false){\n    throw new Error(message);\n  }\n}catch(ex){\n  console.error(ex.message);\n}\n\n// addPageProduct\n\nconst promise1 = paystack.addPageProduct({\n  id: '0826739',\n  products: [473, 292]\n})\n\npromise1.then(function(response){\n   // Error Handling\n   if(response.body.status === false){\n     console.error(response.body.message);\n   }\n   var data = response.body.data;\n}).catch(function (error) {\n  // deal with error\n})\n\n// getCustomer\n\nconst promise2 = paystack.getCustomer({\n  customer_id:'CUS_e24m6SqA6g3Jk889o21'\n})\n\npromise2.then(function(response){\n  var data = response.body\n  \n}).catch(function(error){\n  // deal with error\n})\n\n// createCustomer\n\nconst promise3 = paystack.createCustomer({\n  email:'malik.onyemah@gmail.com',\n  first_name:'Malik',\n  last_name:'Onyemah',\n  phone:'+2347135548369'\n})\n\npromise3.then(function(response){\n  return response.body\n}).then( body =\u003e {\n  return res.status(200).json({id:body.data.id})\n})\n\n// setRiskActionOnCustomer\n\nconst promise4 = paystack.setRiskActionOnCustomer({\n  risk_action:'deny',\n  customer_id:'CUS_e24m6SqA6g3Jk889o21'\n})\n\npromise4.then(function (response){\n   const result = response.body\n}).catch(function (error){\n  // deal with error\n})\n\n// createPage\n\nconst promise5 = paystack.createPage({\n  name:'DoorPost Pay',\n  description:'This is payment for every ',\n  amount:300000, // Amount in kobo\n  slug:'5nApBwZkvR',\n  redirect_url:'https://www.localhoster.com/pay/callback',\n  custom_fields: ['phone_number', 'age']\n})\n\npromise5.then(function (response){\n console.log(response.body);\n}).catch(function (error){\n  // deal with error\n})\n\n// initializeTransaction\n\nconst promise6 = paystack.initializeTransaction({\n  reference: \"7PVGX8MEk85tgeEpVDtD\",\n  amount: 500000, // 5,000 Naira (remember you have to pass amount in kobo)\n  email: \"seun045olayinka@gmail.com\",\n  subaccount: \"ACCT_8f4s1eq7ml6rlzj\"\n})\n\npromise6.then(function (response){\n  console.log(response.body);\n}).catch(function (error){\n  // deal with error\n})\n\n// verifyTransaction\n\nconst promise7 = paystack.verifyTransaction({\n  reference: \"7PVGX8MEk85tgeEpVDtD\"\n})\n\npromise7.then(function (response){\n console.log(response.body);\n}).catch(function (error){\n  // deal with error\n})\n\n// listInvoices\n\nconst promise8 = paystack.listInvoices({\n  customer: \"CUS_je02lbimlqixzax\",\n  status: \"pending\",\n  paid: false,\n  currency: \"NGN\"\n})\n\npromise8.then(function (response){\n console.log(response.body);\n}).catch(function (error){\n  // deal with error\n})\n\napp.use(async function verifications(req, res, next){\n    let responseBVN = await paystack.resolveBVN({\n      bvn:req.body.bvn //'22283643840404'\n    })\n\n    let responseAcctNum = await paystack.resolveAccountNumber({\n      account_number:req.body.acc_num, // '0004644649'\n      bank_code:req.body.bank_code // '075'\n    })\n\n    next()\n})\n\n```\n\n### Mocking the Instance (for Unit/Integration Tests)\n\u003eSetting up mocks for testing with the paystack instance is now as easy as fliping a switch like so:\n\n```js\n\nlet PayStack = require('paystack-node')\n\nlet APIKEY = 'sk_live_2hWyQ6HW73jS8p1IkXmSWOlE4y9Inhgyd6g5f2R7'\nconst environment = process.env.NODE_ENV\n\nconst paystack = new PayStack(APIKEY, environment)\n\n// call the real API methods\nconst { body } = paystack.chargeCard({\n  card:{\n    number: '5399837841116788', // mastercard\n    cvv: '324',\n    expiry_year: '2024',\n    expiry_month: '08'\n  },\n  email: 'me.biodunch@xyz.ng',\n  amount: 15600000 // 156,000 Naira in kobo\n})\n\n// mocking call made on the constructor\n// start mocking\nPayStack.engageMock()\n\n// call the mock API methods\nconst { body } = await paystack.chargeBank({\n  bank: {\n    code: \"050\", // Eco Bank\n    account_number: \"0000000000\"\n  },\n  email: 'me.biodunch@xyz.ng',\n  amount: 1850000 // 18,500 Naira in kobo\n})\n\n// replace mocked methods (! don't use arrow functions !)\nPayStack.mockMacro(\n  'getCustomers', \n  async function getCustomers (reqPayload = {}) {\n    // validation for (reqPayload) is already taken care of!\n\n    // @TODO: optionally, connect to a in-memory db (redis) for mocking purposes\n\n    // return mocked response object\n    return { status: 200, body: { status: \"success\", data: reqPayload } };\n})\n\nconst { body } = await paystack.getCustomers({\n  customer_id:'CUS_e24m6SqA6g3Jk889o21'\n})\n\n// stop mocking\n// mocking call made on the constructor\nPayStack.disengageMock()\n```\n\n## API Resources\n\n\u003eEach method expects an object literal with both **route parameters** and **request parameters (query / body)**. Please, go through the _src/endpoints_ folder to see the specific items that should make up the object literal for each method\n\n- customers\n  - paystack.createCustomer()\n  - paystack.getCustomer()\n  - paystack.listCustomer()\n  - paystack.updateCustomer()\n  - paystack.deactivateAuthOnCustomer()\n  - paystack.setRiskActionOnCustomer()\n- disputes\n  - paystack.listDisputes()\n- dedicated nuban\n  - paystack.createDedicatedNuban()\n  - paystack.listDedicatedNubans()\n  - paystack.fetchDedicatedNuban()\n  - paystack.deactivateDedicatedNuban()\n- invoices\n  - paystack.createInvoice()\n  - paystack.getMetricsForInvoices()\n  - paystack.sendInvoiceNotification()\n  - paystack.listInvoice()\n  - paystack.updateInvoice()\n  - paystack.verifyInvoice()\n  - paystack.finalizeInvoiceDraft()\n  - paystack.archiveInvoice()\n  - paystack.markInvoiceAsPaid()\n- settlements\n  - paystack.getSettlements()\n- payment sessions {control panel}\n  - paystack.getPaymentSessionTimeout()\n  - paystack.updatePaymentSessionTimeout()\n- pages\n  - paystack.createPage()\n  - paystack.listPages()\n  - paystack.getPage()\n  - paystack.updatePage()\n  - paystack.checkSlugAvailability()\n  - paystack.addPageProduct()\n- products\n  - paystack.createProduct()\n  - paystack.listProduct()\n  - paystack.getProduct()\n  - paystack.updateProduct()\n- transactions\n  - paystack.initializeTransaction()\n  - paystack.chargeAuthorization()\n  - paystack.getTransaction()\n  - paystack.listTransaction()\n  - paystack.viewTransactionTimeline()\n  - paystack.transactionTotals()\n  - paystack.exportTransaction()\n  - paystack.requestReauthorization()\n  - paystack.checkAuthorization()\n  - paystack.verifyTransaction()\n  - paystack.partialDebit()\n- plans\n  - paystack.createPlan()\n  - paystack.getPlan()\n  - paystack.listPlan()\n  - paystack.updatePlan()\n- refunds\n  - paystack.createRefund()\n  - paystack.getRefund()\n  - paystack.listRefund()\n- subscriptions\n  - paystack.createSubscription()\n  - paystack.disableSubscription()\n  - paystack.enableSubscription()\n  - paystack.getSubscription()\n  - paystack.listSubscription()\n- subaccounts\n  - paystack.createSubaccount()\n  - paystack.getSubaccount()\n  - paystack.listSubaccount()\n  - paystack.updateSubaccount()\n- verifications\n  - paystack.resolveBVN()\n  - paystack.resolveBVNPremium()\n  - paystack.matchBVN()\n  - paystack.resolveAccountNumber()\n  - paystack.resolveCardBin()\n  - paystack.resolvePhoneNumber()\n- transfers\n  - paystack.initiateTransfer()\n  - paystack.listTransfers()\n  - paystack.fetchTransfer()\n  - paystack.finalizeTransfer()\n  - paystack.initiateBulkTransfer()\n- transfer_recipients\n  - paystack.createTransferRecipient()\n  - paystack.listTransferRecipients()\n  - paystack.updateTransferRecipient()\n  - paystack.deleteTransferRecipient()\n- charges\n  - paystack.chargeCard()\n  - paystack.chargeBank()\n  - paystack.chargeUssd()\n  - paystack.chargeMobileMoney()\n  - paystack.submitPIN()\n  - paystack.submitOTP()\n  - paystack.submitPhone()\n  - paystack.submitBirthday()\n  - paystack.submitAddress()\n  - paystack.checkPendingCharge()\n- miscellanous\n  - paystack.listBanks()\n  - paystack.listProviders()\n  - paystack.listCountries()\n\n# License\n\nMIT\n\n# Credits\n\n- [Ifeora Okechukwu](https://twitter.com/isocroft)\n- [Ahmad Abdul-Aziz](https://twitter.com/dev_amaz)\n\n# Contributing\n\nSee the [CONTRIBUTING.md](https://github.com/stitchng/paystack/blob/master/CONTRIBUTING.md) file for info\n\n[npm-image]: https://img.shields.io/npm/v/paystack-node.svg?style=flat-square\n[npm-url]: https://npmjs.org/package/paystack-node\n\n[travis-image]: https://img.shields.io/travis/stitchng/paystack/master.svg?style=flat-square\n[travis-url]: https://travis-ci.org/stitchng/paystack\n\n## Support \n\n**Coolcodes** is a non-profit software foundation (collective) created by **Oparand** - parent company of StitchNG, Synergixe based in Abuja, Nigeria. You'll find an overview of all our work and supported open source projects on our [Facebook Page](https://www.facebook.com/coolcodes/).\n\n\u003eFollow us on facebook if you can to get the latest open source software/freeware news and infomation.\n\nDoes your business depend on our open projects? Reach out and support us on [Patreon](https://www.patreon.com/coolcodes/). All pledges will be dedicated to allocating workforce on maintenance and new awesome stuff.\n","funding_links":["https://www.patreon.com/coolcodes/"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstitchng%2Fpaystack","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstitchng%2Fpaystack","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstitchng%2Fpaystack/lists"}