Skip to content
BusinessBilling

Business

Billing

Plan, invoices, payments and plan changes.

Pilotv1

The owner's Billing screen for a key: plan, subscription, usage, invoices, coupons and plan changes. Amounts are in poisha. billing:read, billing:write and billing:pay are explicit owner choices in no preset, and starting a payment is not a confirmed payment.

Paths are relative to https://app.revisit.cards/v1/developer.

Endpoints

Read the business's Revisit subscription

GET/billing/subscription

Scopebilling:read

Requires the explicit billing:read scope and a key with no branch or program limit. The same view as the owner's Billing screen. Revisit platform billing is in taka (poisha) and a test key is refused with 403 TEST_MODE_BLOCKED. Open while the plan is unpaid.

Errors

  • 403TEST_MODE_BLOCKEDtest mode asked for a real provider (SMS, push, wallet, payment); nothing real is ever sent from a test workspace.
Request
curl "https://app.revisit.cards/v1/developer/billing/subscription" \
  -H "Authorization: Bearer $DEVELOPER_API_KEY"
Response
{
  "data": null,
  "requestId": "33c1bbeb-14a8-4057-91f1-3e217ee6fc96",
  "success": true
}

List the plans this business may choose

GET/billing/plans

Scopebilling:read

Requires billing:read. Public plans and any made for this business, with their price and what they include.

Request
curl "https://app.revisit.cards/v1/developer/billing/plans" \
  -H "Authorization: Bearer $DEVELOPER_API_KEY"
Response
{
  "data": null,
  "requestId": "59b12297-38f1-4e03-8c02-d9c0637a3f49",
  "success": true
}

Read the plan's limits and features

GET/billing/entitlements

Scopebilling:read

Requires billing:read. Limits with what is held, and each feature on or off. API requests are not metered and never raise an invoice; only counter scans, SMS and the plan's other limits count.

Request
curl "https://app.revisit.cards/v1/developer/billing/entitlements" \
  -H "Authorization: Bearer $DEVELOPER_API_KEY"
Response
{
  "data": null,
  "requestId": "e5c0bf48-6520-4403-90d0-22a37241e6ae",
  "success": true
}

Read the scan meter

GET/billing/usage

Scopebilling:read

Requires billing:read. Used, pool, credit, remaining and the reset date; null when the business is not metered. Replayed or repeated API activity is never counted twice.

Request
curl "https://app.revisit.cards/v1/developer/billing/usage" \
  -H "Authorization: Bearer $DEVELOPER_API_KEY"
Response
{
  "data": null,
  "requestId": "3c5e2540-9f8b-48da-bc6c-0c32d7d5d922",
  "success": true
}

Read the SMS balance

GET/billing/sms

Scopebilling:read

Requires billing:read. Pool, bought credit, what campaigns hold and each batch's expiry.

Request
curl "https://app.revisit.cards/v1/developer/billing/sms" \
  -H "Authorization: Bearer $DEVELOPER_API_KEY"
Response
{
  "data": null,
  "requestId": "2fff2faf-afdc-4c65-90f4-101b5754a399",
  "success": true
}

Read the SMS ledger

GET/billing/sms/ledger

Scopebilling:read

Requires billing:read. Newest first, 50 entries a page.

Query

pageinteger
0 to 99999. Default 0.
Request
curl "https://app.revisit.cards/v1/developer/billing/sms/ledger" \
  -H "Authorization: Bearer $DEVELOPER_API_KEY"
Response
{
  "data": null,
  "requestId": "980eed38-7248-4aed-98d4-2b01bc86fcc7",
  "success": true
}

List invoices, newest first

GET/billing/invoices

Scopebilling:read

Requires billing:read. nextCursor is passed back as cursor for the next page.

Query

limitinteger
1 to 100. Default 30.
cursoruuid

Returns 200

itemsobject[]Required
nextCursorstring or nullRequired
Request
curl "https://app.revisit.cards/v1/developer/billing/invoices" \
  -H "Authorization: Bearer $DEVELOPER_API_KEY"
Response
{
  "data": {
    "items": [
      {}
    ],
    "nextCursor": "eyJvZmZzZXQiOjUwfQ"
  },
  "requestId": "7e9dc95e-d4f0-4e83-afa3-1b54aba772ae",
  "success": true
}

Read one invoice

GET/billing/invoices/{invoiceId}

Scopebilling:read

Requires billing:read. Another business's invoice is 404. payment is the latest payment attempt with its checkout link.

Path

invoiceIduuidRequired
Request
curl "https://app.revisit.cards/v1/developer/billing/invoices/e9dc4fa7-2c04-44af-bd44-25a6fe9499ad" \
  -H "Authorization: Bearer $DEVELOPER_API_KEY"
Response
{
  "data": null,
  "requestId": "12534b90-dd12-49c4-a7b4-3b79833ba8ed",
  "success": true
}

Start paying for a plan

POST/billing/invoices/activation

Scopebilling:write

Requires billing:write. Issues the first invoice for the chosen plan, carrying a coupon held from signup. Open while the plan is unpaid. Asking again replaces the open activation invoice, as "Start paying" does in the app.

Send an Idempotency-Key header. Safe to retry.

Body

planIduuidRequired
billingPeriodenum
One of monthly, yearly.

Returns 200

invoiceIduuidRequired
Request
curl -X POST "https://app.revisit.cards/v1/developer/billing/invoices/activation" \
  -H "Authorization: Bearer $DEVELOPER_API_KEY" \
  -H "Idempotency-Key: 5f0c2a8e-7b1d-4c3e-9a6f-0d4b8ef25680" \
  -H "Content-Type: application/json" \
  -d '{
    "planId": "2494503f-92ea-47d6-b56b-883af498ab8e"
  }'
Response
{
  "data": {
    "invoiceId": "e9dc4fa7-2c04-44af-bd44-25a6fe9499ad"
  },
  "requestId": "efe855bd-9ad2-43a4-8f86-0a35c27a6de3",
  "success": true
}

Buy scan credit

POST/billing/invoices/scan-credit

Scopebilling:write

Requires billing:write. An invoice for a top-up of at least 10 taka and at most what the payment provider takes in one payment (amountPoisha, integer). Nothing is charged until the invoice is paid. A retried key never creates a second invoice.

Send an Idempotency-Key header. Safe to retry.

Body

amountPoishaintegerRequired

Returns 200

invoiceIduuidRequired
Request
curl -X POST "https://app.revisit.cards/v1/developer/billing/invoices/scan-credit" \
  -H "Authorization: Bearer $DEVELOPER_API_KEY" \
  -H "Idempotency-Key: 5f0c2a8e-7b1d-4c3e-9a6f-0d4b8edf0acb" \
  -H "Content-Type: application/json" \
  -d '{
    "amountPoisha": 149900
  }'
Response
{
  "data": {
    "invoiceId": "e9dc4fa7-2c04-44af-bd44-25a6fe9499ad"
  },
  "requestId": "e1278d7c-f51f-42ac-a043-ef37fed17657",
  "success": true
}

Buy SMS credit

POST/billing/invoices/sms-credit

Scopebilling:write

Requires billing:write. An invoice for whole segments at the plan's rate; 403 SMS_NOT_APPROVED while Revisit has paused SMS for the shop. A retried key never creates a second invoice.

Send an Idempotency-Key header. Safe to retry.

Body

segmentsintegerRequired

Returns 200

invoiceIduuidRequired

Errors

  • 403SMS_NOT_APPROVED
Request
curl -X POST "https://app.revisit.cards/v1/developer/billing/invoices/sms-credit" \
  -H "Authorization: Bearer $DEVELOPER_API_KEY" \
  -H "Idempotency-Key: 5f0c2a8e-7b1d-4c3e-9a6f-0d4b8eba9144" \
  -H "Content-Type: application/json" \
  -d '{
    "segments": 1
  }'
Response
{
  "data": {
    "invoiceId": "e9dc4fa7-2c04-44af-bd44-25a6fe9499ad"
  },
  "requestId": "ec8d7552-5879-4da8-a56d-edd39cf6648e",
  "success": true
}

Start paying an invoice

POST/billing/invoices/{invoiceId}/pay

Scopebilling:pay

Requires the explicit billing:pay scope. Returns where to pay (checkoutUrl) and the payment reference. This is not a confirmed payment: confirmed is always false, and the invoice stays open until the payment provider's verified result arrives (read GET /billing/payments/{paymentId}). A still-open checkout is handed back, so a retry never starts a second charge; a failed or expired one is replaced by a new attempt. The key never handles card or wallet credentials: the customer pays on the provider's page.

Send an Idempotency-Key header. Safe to retry.

Path

invoiceIduuidRequired

Returns 200

checkoutUrlstringRequired
confirmedfalseRequired
Always false: starting a payment is not a payment.
invoiceIduuidRequired
paymentIduuidRequired
statusenumRequired
One of pending, paid, failed, expired, flagged, refunded.
Request
curl -X POST "https://app.revisit.cards/v1/developer/billing/invoices/e9dc4fa7-2c04-44af-bd44-25a6fe9499ad/pay" \
  -H "Authorization: Bearer $DEVELOPER_API_KEY" \
  -H "Idempotency-Key: 5f0c2a8e-7b1d-4c3e-9a6f-0d4b8e59dd0b"
Response
{
  "data": {
    "checkoutUrl": "<the payment page link>",
    "confirmed": false,
    "invoiceId": "e9dc4fa7-2c04-44af-bd44-25a6fe9499ad",
    "paymentId": "10953fb0-f1a8-4cfd-971c-e7faa7386cf5",
    "status": "pending"
  },
  "requestId": "14dd60f3-c6b3-4f7b-9fd8-14e75ef39916",
  "success": true
}

Read a payment's status

GET/billing/payments/{paymentId}

Scopebilling:read

Requires billing:read. The state Revisit holds (pending, paid, failed, expired, flagged, refunded...) and the invoice's status. Only a verified provider result moves it.

Path

paymentIduuidRequired
Request
curl "https://app.revisit.cards/v1/developer/billing/payments/10953fb0-f1a8-4cfd-971c-e7faa7386cf5" \
  -H "Authorization: Bearer $DEVELOPER_API_KEY"
Response
{
  "data": null,
  "requestId": "184cde1c-a65b-439e-9bff-f714fa537816",
  "success": true
}

List the coupons this business holds or held

GET/billing/coupons

Scopebilling:read

Requires billing:read. Same facts as the owner's coupon list, but the operator who attached a coupon is never named (attachedByRevisit only).

Request
curl "https://app.revisit.cards/v1/developer/billing/coupons" \
  -H "Authorization: Bearer $DEVELOPER_API_KEY"
Response
{
  "data": null,
  "requestId": "481472bf-1ae0-4557-b279-29025912941e",
  "success": true
}

Redeem a coupon code

POST/billing/coupons/redeem

Scopebilling:write

Requires billing:write. Same rules as the app's code box (eligibility, first-payment-only, caps, failed-try limits); every refusal is 422 COUPON_INVALID. A retried key redeems once.

Send an Idempotency-Key header. Safe to retry.

Body

codestringRequired

Errors

  • 422COUPON_INVALID
Request
curl -X POST "https://app.revisit.cards/v1/developer/billing/coupons/redeem" \
  -H "Authorization: Bearer $DEVELOPER_API_KEY" \
  -H "Idempotency-Key: 5f0c2a8e-7b1d-4c3e-9a6f-0d4b8e4ba8fa" \
  -H "Content-Type: application/json" \
  -d '{
    "code": "WELCOME10"
  }'
Response
{
  "data": null,
  "requestId": "5f9fe519-c9a6-42a9-99c2-f206a1294e3b",
  "success": true
}

Read what may change mid-cycle

GET/billing/changes

Scopebilling:read

Requires billing:read. Holdings and the choices for upgrade, outlets, card types and scheduled changes.

Request
curl "https://app.revisit.cards/v1/developer/billing/changes" \
  -H "Authorization: Bearer $DEVELOPER_API_KEY"
Response
{
  "data": null,
  "requestId": "67914b5d-8f0d-48f3-9d6a-1b195c0a91ed",
  "success": true
}

Price an upgrade

GET/billing/changes/upgrade/preview

Scopebilling:read

Requires billing:read. Writes nothing.

Query

planIduuidRequired
Request
curl "https://app.revisit.cards/v1/developer/billing/changes/upgrade/preview?planId=2494503f-92ea-47d6-b56b-883af498ab8e" \
  -H "Authorization: Bearer $DEVELOPER_API_KEY"
Response
{
  "data": null,
  "requestId": "9916dd01-b157-4208-9a54-752f12c74c0f",
  "success": true
}

Price an extra outlet

GET/billing/changes/outlet/preview

Scopebilling:read

Requires billing:read. Writes nothing.

Query

branchIduuidRequired
Request
curl "https://app.revisit.cards/v1/developer/billing/changes/outlet/preview?branchId=5eff65d7-d01c-4bd3-b26a-3d06b21fd005" \
  -H "Authorization: Bearer $DEVELOPER_API_KEY"
Response
{
  "data": null,
  "requestId": "a136797c-d1c1-4765-ab19-0ddd1cd8410c",
  "success": true
}

Price an extra card type

GET/billing/changes/card-type/preview

Scopebilling:read

Requires billing:read. Writes nothing.

Query

cardTypestringRequired
Request
curl "https://app.revisit.cards/v1/developer/billing/changes/card-type/preview?cardType=stamp" \
  -H "Authorization: Bearer $DEVELOPER_API_KEY"
Response
{
  "data": null,
  "requestId": "0c973a1e-269a-41e6-ab9e-59c6a2a19872",
  "success": true
}

Price a downgrade or removal from the renewal on

POST/billing/changes/schedule/preview

Scopebilling:read

Requires billing:read (a POST only because it takes a body). Writes nothing and needs no operation key.

Body

planIduuid
releaseOutletsuuid[]
releaseTypesstring[]
Request
curl -X POST "https://app.revisit.cards/v1/developer/billing/changes/schedule/preview" \
  -H "Authorization: Bearer $DEVELOPER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "planId": "2494503f-92ea-47d6-b56b-883af498ab8e",
    "releaseOutlets": [
      "d9b88e45-e52c-41b3-8ade-0f70a06fbb71"
    ]
  }'
Response
{
  "data": null,
  "requestId": "f64d66d6-de20-4b8a-b28f-87dd2dce2fc9",
  "success": true
}

Upgrade the plan

POST/billing/changes/upgrade

Scopebilling:write

Requires billing:write. Applies at once when nothing is due, otherwise answers with the invoice to pay; the new plan starts when it is paid. A retried key never makes a second invoice.

Send an Idempotency-Key header. Safe to retry.

Body

planIduuidRequired
Request
curl -X POST "https://app.revisit.cards/v1/developer/billing/changes/upgrade" \
  -H "Authorization: Bearer $DEVELOPER_API_KEY" \
  -H "Idempotency-Key: 5f0c2a8e-7b1d-4c3e-9a6f-0d4b8ef95ff4" \
  -H "Content-Type: application/json" \
  -d '{
    "planId": "2494503f-92ea-47d6-b56b-883af498ab8e"
  }'
Response
{
  "data": null,
  "requestId": "37455e82-0208-4da5-a296-410822f41238",
  "success": true
}

Buy an extra outlet

POST/billing/changes/outlet

Scopebilling:write

Requires billing:write. Same eligibility and price as the app.

Send an Idempotency-Key header. Safe to retry.

Body

branchIduuidRequired
Request
curl -X POST "https://app.revisit.cards/v1/developer/billing/changes/outlet" \
  -H "Authorization: Bearer $DEVELOPER_API_KEY" \
  -H "Idempotency-Key: 5f0c2a8e-7b1d-4c3e-9a6f-0d4b8e758d14" \
  -H "Content-Type: application/json" \
  -d '{
    "branchId": "5eff65d7-d01c-4bd3-b26a-3d06b21fd005"
  }'
Response
{
  "data": null,
  "requestId": "35c056f3-a0fc-42c8-9ea0-8a4c01b0b48f",
  "success": true
}

Buy an extra card type

POST/billing/changes/card-type

Scopebilling:write

Requires billing:write. Same eligibility and price as the app.

Send an Idempotency-Key header. Safe to retry.

Body

cardTypestringRequired
Request
curl -X POST "https://app.revisit.cards/v1/developer/billing/changes/card-type" \
  -H "Authorization: Bearer $DEVELOPER_API_KEY" \
  -H "Idempotency-Key: 5f0c2a8e-7b1d-4c3e-9a6f-0d4b8ed98665" \
  -H "Content-Type: application/json" \
  -d '{
    "cardType": "stamp"
  }'
Response
{
  "data": null,
  "requestId": "0c3003bd-987f-43df-bbbf-f5996ab5766b",
  "success": true
}

Schedule a downgrade or removal for the renewal

PUT/billing/changes/schedule

Scopebilling:write

Requires billing:write. Answers with the subscription view.

Send an Idempotency-Key header. Safe to retry.

Body

planIduuid
releaseOutletsuuid[]
releaseTypesstring[]
Request
curl -X PUT "https://app.revisit.cards/v1/developer/billing/changes/schedule" \
  -H "Authorization: Bearer $DEVELOPER_API_KEY" \
  -H "Idempotency-Key: 5f0c2a8e-7b1d-4c3e-9a6f-0d4b8eace02d" \
  -H "Content-Type: application/json" \
  -d '{
    "planId": "2494503f-92ea-47d6-b56b-883af498ab8e",
    "releaseOutlets": [
      "d9b88e45-e52c-41b3-8ade-0f70a06fbb71"
    ]
  }'
Response
{
  "data": null,
  "requestId": "d883e577-150f-4b3f-b541-2fea3fedf34d",
  "success": true
}

Cancel the scheduled change

DELETE/billing/changes/schedule

Scopebilling:write

Requires billing:write. 409 once the renewal invoice already includes it.

Send an Idempotency-Key header. Safe to retry.

Request
curl -X DELETE "https://app.revisit.cards/v1/developer/billing/changes/schedule" \
  -H "Authorization: Bearer $DEVELOPER_API_KEY" \
  -H "Idempotency-Key: 5f0c2a8e-7b1d-4c3e-9a6f-0d4b8ec70c93"
Response
{
  "data": null,
  "requestId": "e7c80353-3ab7-4ebe-a2dd-1d9131f29c68",
  "success": true
}

Choose whether the next renewal bills a month or a year

PUT/billing/changes/renewal-period

Scopebilling:write

Requires billing:write. Open while the plan is unpaid. An open renewal invoice is replaced; one with a payment under way refuses the switch.

Send an Idempotency-Key header. Safe to retry.

Body

billingPeriodenumRequired
One of monthly, yearly.
Request
curl -X PUT "https://app.revisit.cards/v1/developer/billing/changes/renewal-period" \
  -H "Authorization: Bearer $DEVELOPER_API_KEY" \
  -H "Idempotency-Key: 5f0c2a8e-7b1d-4c3e-9a6f-0d4b8edad063" \
  -H "Content-Type: application/json" \
  -d '{
    "billingPeriod": "monthly"
  }'
Response
{
  "data": null,
  "requestId": "93bae1ca-a06a-4b75-804d-5760089cd0e9",
  "success": true
}

Choose which paused outlet, card or design is live after a downgrade

POST/billing/downgrade/swap

Scopebilling:write

Requires billing:write.

Send an Idempotency-Key header. Safe to retry.

Body

activateIduuidRequired
deactivateIduuidRequired
kindenumRequired
One of branch, card, design.
Request
curl -X POST "https://app.revisit.cards/v1/developer/billing/downgrade/swap" \
  -H "Authorization: Bearer $DEVELOPER_API_KEY" \
  -H "Idempotency-Key: 5f0c2a8e-7b1d-4c3e-9a6f-0d4b8efad97f" \
  -H "Content-Type: application/json" \
  -d '{
    "activateId": "0e989e3e-88fc-419c-adda-795d539f4b65",
    "deactivateId": "5f77612c-52b7-4fae-bfd9-ccbc0c107620",
    "kind": "branch"
  }'
Response
{
  "data": null,
  "requestId": "5630e81d-a853-489a-9791-7a12c6fd90d1",
  "success": true
}