Skip to content
PayMoreDevelopers
Log in

PayMore API

REST API for approved business accounts. List plans, read the business balance, submit KYC, and request and manage cards. Requests and responses are JSON over HTTPS.

  • REST
  • JSON
  • HTTPS
  • X-API-Key

Base URL: https://api.paymore.io/v1

Request an API key

PayMore issues the key after the business account is reviewed. There is no self-serve key. Active keys are listed in the business portal once issued.

PayMore is operated by Due Pay Limited (Hong Kong).

api.paymore.io
$ curl "https://api.paymore.io/v1/plans"
{
  "plans": [
    {
      "plan": "startup",
      "monthly_fee": 500,
      "card_issuance_fee": 10
    }
  ],
  "currency": "USD"
}

Trimmed live response

Three steps

  1. 01

    Request a key

    Write to [email protected]. PayMore sends the key after the account is approved. There is no self-serve key.

  2. 02

    Call a public route

    GET https://api.paymore.io/v1/plans returns the fee schedules with no key.

  3. 03

    Send the key

    Put pm_live_xxx in the X-API-Key header, then call GET /balance.

Overview

REST API for approved business accounts. List plans, read the business balance, submit KYC, and request and manage cards. Requests and responses are JSON over HTTPS.

GEThttps://api.paymore.io/v1Public

Service index

Returns the service name, version, and route list. GET https://api.paymore.io/ and GET https://api.paymore.io/v1/ return the same body. The status field describes the index. It is not an uptime guarantee.

Parameters

This route has no parameters.

curl "https://api.paymore.io/v1"

Response

{
  "name": "PayMore API",
  "version": "v1",
  "status": "operational",
  "base_url": "https://api.paymore.io/v1",
  "documentation": "https://paymore.io/developers",
  "endpoints": {
    "public": ["GET /plans"],
    "account": ["GET /balance", "GET /account", "GET /transactions"],
    "kyc": ["POST /kyc/submit", "GET /kyc/{external_user_id}", "GET /end-users"],
    "cards": [
      "POST /cards/issue",
      "GET /cards",
      "GET /cards/{card_id}",
      "POST /cards/{card_id}/fund",
      "POST /cards/{card_id}/unload",
      "POST /cards/{card_id}/freeze",
      "POST /cards/{card_id}/unfreeze"
    ]
  }
}

Authentication

Send the key in the X-API-Key header. Authorization: Bearer is also accepted. A live key starts with pm_live_. Public routes do not require a key.

The key can spend the business balance. Use it only from your server. If a key is exposed, write to PayMore to revoke it.

curl "https://api.paymore.io/v1/balance" \
  -H "X-API-Key: pm_live_xxx"

Response

{
  "balance": 1500,
  "currency": "USD"
}

Base URL

Paths below are relative to this base unless a full URL is shown.

https://api.paymore.io/v1

curl "https://api.paymore.io/v1"

Response

{
  "name": "PayMore API",
  "version": "v1",
  "status": "operational",
  "base_url": "https://api.paymore.io/v1",
  "documentation": "https://paymore.io/developers",
  "endpoints": {
    "public": ["GET /plans"],
    "account": ["GET /balance", "GET /account", "GET /transactions"],
    "kyc": ["POST /kyc/submit", "GET /kyc/{external_user_id}", "GET /end-users"],
    "cards": [
      "POST /cards/issue",
      "GET /cards",
      "GET /cards/{card_id}",
      "POST /cards/{card_id}/fund",
      "POST /cards/{card_id}/unload",
      "POST /cards/{card_id}/freeze",
      "POST /cards/{card_id}/unfreeze"
    ]
  }
}

Errors

An error is a JSON body with an error string. Some errors add fields such as required_fee or limit_per_minute.

  • 400Invalid request: missing fields, invalid JSON, or an invalid amount.
  • 401Key missing, not starting with pm_live_, unknown, or revoked.
  • 402Business balance does not cover the amount or fee.
  • 403Business account is not active, KYC is not approved, or the card is not in the required state.
  • 404Route, end user, or card was not found. An unknown route also returns available_endpoints.
  • 409The card state does not allow freeze or unfreeze.
  • 429Rate limit exceeded. Wait 60 seconds.
  • 500Server error. The body is Internal server error.
curl "https://api.paymore.io/v1/balance"

Response

{
  "error": "Missing or invalid API key. Use header X-API-Key or Authorization: Bearer pm_live_..."
}

Rate limits

Authenticated requests are counted per business over a rolling 60 seconds:

PlanRequests per minute
Startup60
Enterprise300
Premium300

Over the limit, the API returns 429 with Retry-After: 60. The body includes limit_per_minute.

curl "https://api.paymore.io/v1/balance" \
  -H "X-API-Key: pm_live_xxx"

Response

{
  "error": "Rate limit exceeded. Retry after 60 seconds.",
  "limit_per_minute": 60
}

Pagination

List routes (transactions, end users, cards) take limit from 1 to 100 (default 50) and offset from 0 to 100000 (default 0).

curl "https://api.paymore.io/v1/transactions?limit=50&offset=0" \
  -H "X-API-Key: pm_live_xxx"

Response

{
  "transactions": [
    {
      "id": "c7a1e9d2-5b3f-4c8e-a6d1-0f2b4e8c9a71",
      "business_id": "3f1c2b7a-8d4e-4a61-9b0f-2e6d8c5a1f34",
      "type": "card_funding",
      "amount": -102,
      "description": "Card funding",
      "reference_id": null,
      "created_at": "2026-10-02T14:05:11.208Z"
    }
  ],
  "total": 1,
  "limit": 50,
  "offset": 0
}

GET/balance#API key

Get balance

Balance of the business account linked to the key, in USD. Fees and card funding are paid from this balance.

Parameters

This route has no parameters.

curl "https://api.paymore.io/v1/balance" \
  -H "X-API-Key: pm_live_xxx"

Response

{
  "balance": 1500,
  "currency": "USD"
}

GET/account#API key

Get account

The business account linked to the key.

Parameters

This route has no parameters.

curl "https://api.paymore.io/v1/account" \
  -H "X-API-Key: pm_live_xxx"

Response

{
  "account": {
    "id": "3f1c2b7a-8d4e-4a61-9b0f-2e6d8c5a1f34",
    "company_name": "Example Ltd",
    "company_email": "[email protected]",
    "plan": "startup",
    "status": "active",
    "business_balance": 1500,
    "created_at": "2026-09-14T10:22:31.512Z"
  }
}

GET/transactions#API key

List transactions

Business ledger, newest first. Debits are negative. Filter with type: deposit, fee, card_issuance, card_funding, kyc_fee, subscription, withdrawal, or refund. Page with limit 1–100 (default 50) and offset 0–100000 (default 0).

Parameters

NameInRequiredTypeDescription
typequeryOptionalstringdeposit, fee, card_issuance, card_funding, kyc_fee, subscription, withdrawal, or refund.
limitqueryOptionalintegerPage size from 1 to 100. Default 50.
offsetqueryOptionalintegerRows to skip, from 0 to 100000. Default 0.
curl "https://api.paymore.io/v1/transactions" \
  -H "X-API-Key: pm_live_xxx"

Response

{
  "transactions": [
    {
      "id": "c7a1e9d2-5b3f-4c8e-a6d1-0f2b4e8c9a71",
      "business_id": "3f1c2b7a-8d4e-4a61-9b0f-2e6d8c5a1f34",
      "type": "card_funding",
      "amount": -102,
      "description": "Card funding",
      "reference_id": null,
      "created_at": "2026-10-02T14:05:11.208Z"
    }
  ],
  "total": 1,
  "limit": 50,
  "offset": 0
}

POST/kyc/submit#API key

Submit KYC

Creates an end user, or resubmits an existing one, for review. Required: external_user_id, first_name, last_name, email, phone, country, address, id_number. Optional: dob (YYYY-MM-DD), passport_number, document_type (passport, national_id, or driving_license), document_front_base64, document_back_base64, selfie_base64. If your plan has a KYC fee, it is charged from the business balance on each submission.

If the same ID or passport number already exists under your account, the response may include has_duplicate_warnings: true.

Parameters

NameInRequiredTypeDescription
external_user_idbodyRequiredstringYour id for this person.
first_namebodyRequiredstringGiven name.
last_namebodyRequiredstringFamily name.
emailbodyRequiredstringEmail address.
phonebodyRequiredstringPhone number.
countrybodyRequiredstringCountry code, such as AE.
addressbodyRequiredstringStreet address.
id_numberbodyRequiredstringNational or identity number.
dobbodyOptionalstringDate of birth, YYYY-MM-DD.
passport_numberbodyOptionalstringPassport number.
document_typebodyOptionalstringpassport, national_id, or driving_license.
document_front_base64bodyOptionalstringFront of the document, base64.
document_back_base64bodyOptionalstringBack of the document, base64.
selfie_base64bodyOptionalstringSelfie image, base64.
curl -X POST "https://api.paymore.io/v1/kyc/submit" \
  -H "X-API-Key: pm_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{  "external_user_id": "user_123",  "first_name": "Amina",  "last_name": "Hassan",  "email": "[email protected]",  "phone": "+971500000000",  "country": "AE",  "address": "Example tower",  "id_number": "784-1990-0000000-0",  "dob": "1990-01-15",  "document_type": "passport"}'

Response

{
  "success": true,
  "end_user_id": "550e8400-e29b-41d4-a716-446655440000",
  "external_user_id": "user_123",
  "kyc_status": "pending"
}

GET/kyc/{external_user_id}#API key

Get KYC status

Status for one end user. kyc_status is none, pending, approved, or rejected.

Parameters

NameInRequiredTypeDescription
external_user_idpathRequiredstringThe id you sent when the end user was created.
curl "https://api.paymore.io/v1/kyc/user_123" \
  -H "X-API-Key: pm_live_xxx"

Response

{
  "user": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "external_user_id": "user_123",
    "first_name": "Amina",
    "last_name": "Hassan",
    "email": "[email protected]",
    "phone": "+971500000000",
    "kyc_status": "approved",
    "kyc_submitted_at": "2026-10-01T09:12:44.103Z",
    "kyc_reviewed_at": "2026-10-01T15:30:02.871Z"
  }
}

GET/end-users#API key

List end users

End users under your account, newest first. Filter with kyc_status. Same limit and offset bounds as the transaction list.

Parameters

NameInRequiredTypeDescription
kyc_statusqueryOptionalstringnone, pending, approved, or rejected.
limitqueryOptionalintegerPage size from 1 to 100. Default 50.
offsetqueryOptionalintegerRows to skip, from 0 to 100000. Default 0.
curl "https://api.paymore.io/v1/end-users" \
  -H "X-API-Key: pm_live_xxx"

Response

{
  "end_users": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "external_user_id": "user_123",
      "first_name": "Amina",
      "last_name": "Hassan",
      "email": "[email protected]",
      "phone": "+971500000000",
      "kyc_status": "approved",
      "kyc_submitted_at": "2026-10-01T09:12:44.103Z",
      "kyc_reviewed_at": "2026-10-01T15:30:02.871Z",
      "created_at": "2026-10-01T09:12:44.103Z"
    }
  ],
  "total": 1,
  "limit": 50,
  "offset": 0
}

POST/cards/issue#API key

Request a card

Requests a card for an end user whose KYC status is approved. external_user_id is required. card_type_id is optional. The request starts as pending until PayMore activates it. If your plan has an issuance fee, it is charged when the request is created.

Parameters

NameInRequiredTypeDescription
external_user_idbodyRequiredstringEnd user whose KYC status is approved.
card_type_idbodyOptionalstringOptional card type id.
curl -X POST "https://api.paymore.io/v1/cards/issue" \
  -H "X-API-Key: pm_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{  "external_user_id": "user_123"}'

Response

{
  "success": true,
  "card_request_id": "9b2f6c1e-4a7d-4e2b-8c3f-1d5e7a9b0c2d",
  "status": "pending",
  "message": "Card request submitted. Our admin team will activate it and fill in card details. Check status via GET /cards/{card_id}."
}

GET/cards#API key

List cards

Cards on your account, newest first. Status is pending, approved, reviewing, active, rejected, cancelled, frozen, or disabled. Filter with status. This list does not return a card number or CVV.

Parameters

NameInRequiredTypeDescription
statusqueryOptionalstringpending, approved, reviewing, active, rejected, cancelled, frozen, or disabled.
limitqueryOptionalintegerPage size from 1 to 100. Default 50.
offsetqueryOptionalintegerRows to skip, from 0 to 100000. Default 0.
curl "https://api.paymore.io/v1/cards" \
  -H "X-API-Key: pm_live_xxx"

Response

{
  "cards": [
    {
      "id": "9b2f6c1e-4a7d-4e2b-8c3f-1d5e7a9b0c2d",
      "end_user_id": "550e8400-e29b-41d4-a716-446655440000",
      "card_type_id": null,
      "status": "active",
      "card_balance": 100,
      "daily_limit": null,
      "created_at": "2026-10-02T11:00:00.000Z",
      "updated_at": "2026-10-02T14:05:11.208Z",
      "end_user": {
        "external_user_id": "user_123",
        "first_name": "Amina",
        "last_name": "Hassan"
      }
    }
  ],
  "total": 1,
  "limit": 50,
  "offset": 0
}

GET/cards/{card_id}#API key

Get card

One card. card_id is a UUID. Only while status is active, the response includes the last four digits as card_last4 and the expiry as card_expiry. The full card number and CVV are never returned.

Parameters

NameInRequiredTypeDescription
card_idpathRequireduuidCard id returned by issue, list, or get.
curl "https://api.paymore.io/v1/cards/9b2f6c1e-4a7d-4e2b-8c3f-1d5e7a9b0c2d" \
  -H "X-API-Key: pm_live_xxx"

Response

{
  "card": {
    "id": "9b2f6c1e-4a7d-4e2b-8c3f-1d5e7a9b0c2d",
    "end_user_id": "550e8400-e29b-41d4-a716-446655440000",
    "status": "active",
    "card_balance": 100,
    "daily_limit": null,
    "created_at": "2026-10-02T11:00:00.000Z",
    "updated_at": "2026-10-02T14:05:11.208Z",
    "end_user": {
      "external_user_id": "user_123",
      "first_name": "Amina",
      "last_name": "Hassan"
    },
    "card_last4": "4242",
    "card_expiry": "10/29"
  }
}

POST/cards/{card_id}/fund#API key

Fund card

Loads a USD amount onto an active card. amount is a positive number, rounded to cents, with a maximum of 10000 per request. The business balance is charged the amount plus your plan’s funding fee (the greater of the percentage and the minimum).

Parameters

NameInRequiredTypeDescription
card_idpathRequireduuidCard id returned by issue, list, or get.
amountbodyRequirednumberPositive USD amount, rounded to cents, maximum 10000.
curl -X POST "https://api.paymore.io/v1/cards/9b2f6c1e-4a7d-4e2b-8c3f-1d5e7a9b0c2d/fund" \
  -H "X-API-Key: pm_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{  "amount": 100}'

Response

{
  "success": true,
  "funded_amount": 100,
  "fee": 2,
  "new_card_balance": 100
}

POST/cards/{card_id}/unload#API key

Unload card

Moves an amount from an active card back to the business balance. This route does not add a fee. The amount cannot exceed the card balance.

Parameters

NameInRequiredTypeDescription
card_idpathRequireduuidCard id returned by issue, list, or get.
amountbodyRequirednumberPositive USD amount. It cannot exceed the card balance. This route adds no fee.
curl -X POST "https://api.paymore.io/v1/cards/9b2f6c1e-4a7d-4e2b-8c3f-1d5e7a9b0c2d/unload" \
  -H "X-API-Key: pm_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{  "amount": 50}'

Response

{
  "success": true,
  "unloaded_amount": 50,
  "new_card_balance": 50
}

POST/cards/{card_id}/freeze#API key

Freeze card

Freezes an active card. No request body. A frozen card cannot be funded or unloaded until it is unfrozen.

Parameters

NameInRequiredTypeDescription
card_idpathRequireduuidCard id returned by issue, list, or get.
curl -X POST "https://api.paymore.io/v1/cards/9b2f6c1e-4a7d-4e2b-8c3f-1d5e7a9b0c2d/freeze" \
  -H "X-API-Key: pm_live_xxx"

Response

{
  "success": true,
  "card_id": "9b2f6c1e-4a7d-4e2b-8c3f-1d5e7a9b0c2d",
  "status": "frozen"
}

POST/cards/{card_id}/unfreeze#API key

Unfreeze card

Sets a frozen card back to active. No request body.

Parameters

NameInRequiredTypeDescription
card_idpathRequireduuidCard id returned by issue, list, or get.
curl -X POST "https://api.paymore.io/v1/cards/9b2f6c1e-4a7d-4e2b-8c3f-1d5e7a9b0c2d/unfreeze" \
  -H "X-API-Key: pm_live_xxx"

Response

{
  "success": true,
  "card_id": "9b2f6c1e-4a7d-4e2b-8c3f-1d5e7a9b0c2d",
  "status": "active"
}

GET/plans#Public

List plans

Returns USD fee schedules for the startup, enterprise, and premium plans. No key is required. The sample shows the startup shape. Call the endpoint for the current figures of all three plans.

GET https://api.paymore.io/plans returns the same body.

Parameters

This route has no parameters.

curl "https://api.paymore.io/v1/plans"

Response

{
  "plans": [
    {
      "plan": "startup",
      "monthly_fee": 500,
      "card_issuance_fee": 10,
      "card_funding_fee_pct": 2,
      "card_funding_fee_min": 0.5,
      "monthly_maintenance_fee": 1,
      "decline_fee": 0.4,
      "crossborder_fee_pct": 2.5,
      "crossborder_fee_min": 0.5,
      "wallet_tokenization_fee": 1,
      "wallet_deposit_fee_pct": 3,
      "wallet_deposit_fee_min": 2,
      "wallet_withdrawal_fee": 5,
      "kyc_verification_fee": 1,
      "chargeback_fee": 30,
      "prepay_discount_6m": 0,
      "prepay_discount_1y": 0
    }
  ],
  "currency": "USD"
}

Coming soon

There is no international-transfer API.

Webhooks

PayMore does not send webhooks, and there is no signature scheme for an incoming request.

SDK

There is no SDK. The samples use curl, fetch, and Python’s standard urllib.

  • Visa
  • Mastercard
  • Visa Secure
  • Mastercard Identity Check

Visa, Visa Secure, Mastercard and Mastercard Identity Check are trademarks of their respective owners. Card security services are provided through our third-party card issuing provider.

PayMore is operated by Due Pay Limited (Hong Kong).

Due Pay Limited

Company incorporated in Hong Kong

Company No. 79365245

No. 5, 17/F, Strand 50, 50 Bonham Strand, Sheung Wan, Hong Kong

Representative Office (Dubai)

Business Centre, 2nd Floor, Al Fattan Tower, JBR, Dubai, UAE

PayMore is not a bank and does not hold customer funds.

All card issuance and financial processing services are provided strictly by third-party service providers.

© 2026 PayMore. All rights reserved.