{"id":13499326,"url":"https://github.com/ElementsProject/paypercall","last_synced_at":"2025-03-29T04:31:04.740Z","repository":{"id":57321088,"uuid":"123939363","full_name":"ElementsProject/paypercall","owner":"ElementsProject","description":"Charge for HTTP APIs on a pay-per-call basis with Bitcoin and Lightning :zap:","archived":false,"fork":false,"pushed_at":"2021-09-20T12:56:32.000Z","size":70,"stargazers_count":150,"open_issues_count":6,"forks_count":17,"subscribers_count":13,"default_branch":"master","last_synced_at":"2025-03-18T11:14:58.490Z","etag":null,"topics":["apis","bitcoin","lightning","lightning-charge","micropayments","nanopayments","pay-per-call"],"latest_commit_sha":null,"homepage":"https://www.blockstream.com/2018/03/25/paypercall-shows-the-full-power-of-lightning-charge.html","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/ElementsProject.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-03-05T15:27:54.000Z","updated_at":"2025-01-06T02:21:27.000Z","dependencies_parsed_at":"2022-08-25T21:01:10.101Z","dependency_job_id":null,"html_url":"https://github.com/ElementsProject/paypercall","commit_stats":null,"previous_names":["shesek/paypercall"],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ElementsProject%2Fpaypercall","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ElementsProject%2Fpaypercall/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ElementsProject%2Fpaypercall/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ElementsProject%2Fpaypercall/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ElementsProject","download_url":"https://codeload.github.com/ElementsProject/paypercall/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246140565,"owners_count":20729797,"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","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":["apis","bitcoin","lightning","lightning-charge","micropayments","nanopayments","pay-per-call"],"created_at":"2024-07-31T22:00:32.222Z","updated_at":"2025-03-29T04:31:04.461Z","avatar_url":"https://github.com/ElementsProject.png","language":"JavaScript","readme":"# paypercall\n\n[![npm release](https://img.shields.io/npm/v/paypercall.svg)](https://www.npmjs.com/package/paypercall)\n[![MIT license](https://img.shields.io/github/license/shesek/paypercall.svg)](https://github.com/shesek/paypercall/blob/master/LICENSE)\n[![Pull Requests Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](http://makeapullrequest.com)\n[![IRC](https://img.shields.io/badge/chat-on%20freenode-brightgreen.svg)](https://webchat.freenode.net/?channels=lightning-charge)\n\nCharge for HTTP APIs on a pay-per-call basis with Bitcoin and Lightning.\n\nWant to require a payment when users take some programmatic action, such as sending an SMS or running imaging processing?\nThat's what `paypercall` is for.\n\nAvailable as an express middleware (where a node.js app makes charges directly)\nor as a reverse proxy (where a reverse proxy requires payment before providing access to an app).\n\nPowered by :zap: [Lightning Charge](https://github.com/ElementsProject/lightning-charge).\n\n## Install\n\n```bash\n$ npm install paypercall\n```\n\n## Server Setup\n\n### As a middleware\n\n`paypercall` can be used as an express middleware to charge payments directly in your node.js apps.\nBelow is an example app that charges 0.1 USD to send SMS messages:\n\n#### app.js\n```js\nconst pay = require('paypercall')({ chargeUrl: ..., chargeToken: ... })\n    , twi = require('twilio')(twilioSid, twilioToken)\n    , app = require('express')()\n\napp.use(require('body-parser').urlencoded())\n\napp.post('/sms', pay(0.1, 'USD'), (req, res, next) =\u003e\n  twi.messages.create({ from: 'paypercall', to: req.body.to, body: req.body.message })\n    .then(msg =\u003e res.send({ success: true, sid: msg.sid }))\n    .catch(next))\n\napp.listen(4000, _ =\u003e console.log('HTTP server running on localhost:4000'))\n```\n\nSee [`ifpaytt`](https://github.com/shesek/ifpaytt) for a more full-fledged application using `paypercall` as a middleware.\n\n### As a reverse proxy\n\nAlternatively, you can develop your HTTP server with no payments awareness\nand use `paypercall` as a reverse proxy to handle payments.\nBelow is an example using a python app:\n\n#### app.py\n```python\nfrom flask import Flask, request\nfrom twilio.rest import Client as Twilio\n\napp = Flask(__name__)\ntwi = Twilio(twilioSid, twilioToken)\n\n@app.route(\"/sms\", methods=['POST'])\ndef sms():\n  msg = twi.messages.create(from='paypercall', to=request.form['to'], body=request.form['message'])\n  return { 'success': True, 'sid': msg.sid }\n\n@app.run(Port=4001)\n```\n\nRun the python app and the `paypercall` proxy:\n\n```bash\n$ FLASK_APP=app.py flask run\n* Running on http://localhost:4001/\n\n$ paypercall --charge-token mySecretToken --upstream-url http://localhost:4001 \\\n             --port 4000 --rates-yaml '{ POST /sms: 0.1 USD }'\nHTTP reverse proxy running on http://localhost:4000, proxying to http://localhost:4001\n```\n\nYou will now have the python app running on port 4001 (providing API calls free of charge)\nand the `paypercall` reverse proxy running on port 4000 (charging on a per-call basis).\n\n## Paying for API calls\n\nUsers can access `paypercall`-enabled API endpoints in three steps:\n\n1. Send an empty request (no body) to the `paypercall`-enabled endpoint to get the BOLT11 payment request and the `X-Token` header:\n\n    ```bash\n    $ curl -i -X POST http://localhost:4000/sms\n\n    HTTP/1.1 402 Payment Required\n    Content-Type: application/vnd.lightning.bolt11\n    X-Token: lmbdmJeoSQ0ZCB5egtnph.af1eupleFBVuhN2vrbRuDLTlsnnUPYRzDWdL5HtWykY\n\n    lnbcrt8925560p1pdfh7n2pp54g5avyupe70l988h30u0hy8agpj2z7qsveu7ejhys97j98rgez0...\n    ```\n\n2. Make the payment:\n\n    ```bash\n    $ lightning-cli pay lnbcrt8925560p1pdfh7n2pp54g5avyupe70l988h30u0hy8agpj2z7qsveu7ejhys97j98rgez0...\n    ```\n\n3. Send the request again, this time with the request body and with the `X-Token` header echoed back:\n\n    ```bash\n    $ curl -i -X POST http://localhost:4000/sms \\\n      -H 'X-Token: lmbdmJeoSQ0ZCB5egtnph.af1eupleFBVuhN2vrbRuDLTlsnnUPYRzDWdL5HtWykY' \\\n      -t to=+972-789456123 \\\n      -d message='I got lightning working and all I got was this sms!'\n\n    HTTP/1.1 200 OK\n    Content-Type: application/json\n\n    {\"success\":true,\"sid\":\"SMf34fe622a8fe7565fc15be3ce8bc437e\"}\n    ```\n\n## Documentation\n\n### Middleware\n\n```js\nconst pay = require('paypercall')(options)\n```\n\nReturns a new payment middleware factory. `options` can contain the following fields:\n\n- `chargeUrl`: Lightning Charge server URL (optional, defaults to `http://localhost:9112`)\n- `chargeToken`: Lightning Charge access token (**required**)\n- `dbPath`: Path to sqlite database (optional, defaults to `./paypercall.db`)\n- `currency`: Default currency if none is specified (optional, defaults to `BTC`)\n- `secret`: Secret key used for HMAC tokens (optional, generated based on `chargeToken` by default)\n- `invoiceExp`: How long should invoices be payable for (optional, defaults to 1 hour)\n- `accessExp`: How long should paid access tokens remain valid for (optional, defaults to 1 hour)\n\n```js\nconst payware = pay(amount[, currency])\n```\n\nReturns an express middleware that requires a payment of `amount` units of `currency`\n(or the default currency if none provided) before letting requests pass through.\n\nCan be used as following:\n\n```js\nconst pay = require('paypercall')({ chargeToken: 'myToken', currency: 'EUR' })\n    , app = require('express')\n\n// charge requests to a specific route\napp.post('/sms', pay(0.15), (req, res) =\u003e { /* send SMS */ })\n\n// charge all requests to /paid-apis/*\napp.use('/paid-apis', pay(0.25))\n\n// dynamic pricing (should only be based on the method and path)\napp.post('/ocr/:type', (req, res, next) =\u003e {\n  pay(getPriceForType(req.params.type))(req, res, (err) =\u003e {\n    if (err) return next(err)\n    // payment succesfull, run OCR\n    // (the paid invoice is accessible at `req.invoice`)\n  })\n})\n```\n\n### Reverse proxy\n\n```bash\n$ paypercall --help\n\n  Charge for HTTP APIs on a pay-per-call basis with Bitcoin and Lightning\n\n  Usage\n    $ paypercall [options]\n\n  Options\n    -c, --charge-url \u003curl\u003e      lightning charge server url [default: http://localhost:9112]\n    -t, --charge-token \u003ctoken\u003e  lightning charge access token [required]\n\n    -u, --upstream-url \u003curl\u003e    the upstream server to reverse proxy [required]\n    -r, --rates-path \u003cpath\u003e     path to YAML file mapping from endpoints to rates [default: ./rates.yaml]\n    -y, --rates-yaml \u003cyaml\u003e     YAML string to use instead of reading from {rates-path}\n    -x, --currency \u003cname\u003e       default rate currency if none is specified [default: BTC]\n    -d, --db-path \u003cpath\u003e        path to store sqlite database [default: ./payperclick.db]\n\n    --invoice-expiry \u003csec\u003e      how long should invoices be payable for [default: 1 hour]\n    --access-expiry \u003csec\u003e       how long should paid access tokens remain valid for [default: 1 hour]\n    --token-secret \u003csecret\u003e     secret key used for HMAC tokens [default: generated based on {charge-token}]\n\n    -p, --port \u003cport\u003e           http server port [default: 4000]\n    -i, --host \u003chost\u003e           http server listen address [default: 127.0.0.1]\n    -e, --node-env \u003cenv\u003e        nodejs environment mode [default: production]\n    -h, --help                  output usage information\n    -v, --version               output version number\n\n  Example\n    $ payperclick -t myAccessToken -u http://upstream-server.com/ \\\n                  -y '{ POST /sms: 0.0001 BTC, PUT /page/:id: 0.0002 BTC }'\n```\n\n## License\nMIT\n","funding_links":[],"categories":["Developer Resources"],"sub_categories":["Libraries"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FElementsProject%2Fpaypercall","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FElementsProject%2Fpaypercall","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FElementsProject%2Fpaypercall/lists"}