PayUp Public Payment API (1.0.0)
Download OpenAPI specification:Download
The PayUp public payment surface. These endpoints power both the hosted checkout experience (frontend integrations, via the SDK token) and direct backend integrations (via API keys).
There are four short-lived tokens involved in a payment:
- Creation SDK token (
sdk_token, ~1h) — used only to create a payment session. Never placed in the browser redirect URL.- Frontend — from
POST /v1/tokenize(integrationType=frontend). Used by the web SDK onPOST /v1/checkout/web/session. - Backend — from
POST /v1/auth(integrationType=backend). Used by server integrations onPOST /v1/checkout/backend/session.
- Frontend — from
- Checkout token (
sdk_token, ~1h, session-scoped) — minted when a session is created and appended toredirectUrlas?sdk_token=…. This is the only token the hosted checkout page receives. It is bound to a singlesessionIdand carries onlypayment:send_otpandpayment:verify_otp— it cannot create sessions or set product prices. - Payment verification token (
payment_verification, ~5m) — returned byPOST /v1/checkout/verification/verifyafter the customer proves ownership of their email or phone via OTP. Sent asAuthorization: Bearer <jwt>toPOST /v1/payments/process.
Creation tokens carry integrationType (frontend | backend):
- frontend — may link existing products (
product:link) on/checkout/web/session. Cannot set product prices inline or pre-set a customer. Requires a verified merchantOriginheader. - backend — may additionally create inline/ad-hoc products
(
product:create) and pre-set a locked customer (customer:create/customer:select) on/checkout/backend/session. Server-to-server; noOriginrequired.
Liveness endpoints live outside this spec's server prefix:
GET /health and GET /api/health.
Exchange API keys for a backend creation SDK token
Backend integrations exchange their public/secret API key pair for a
creation SDK token (integrationType=backend). Use this token on
POST /v1/checkout/backend/session only — do not pass it to the browser.
The secret key is sent as a Bearer token and the public key via the
x-public-key header (or the publicKey body field).
Authorizations:
Request Body schema: application/json
| publicKey | string Public key ( |
Responses
Request samples
- Payload
{- "publicKey": "pk_live_8f3a..."
}Response samples
- 200
- 401
- 500
{- "success": true,
- "token": "string",
- "expiresIn": "1h",
- "environment": "sandbox",
- "integrationType": "frontend",
- "permissions": [
- "string"
], - "modules": [
- "string"
]
}Exchange a client token for a frontend creation SDK token
Frontend integrations exchange a publishable client token (tk_*) for
a short-lived creation SDK token (integrationType=frontend). Use
this token on POST /v1/checkout/web/session only — the hosted checkout
page receives a separate session-scoped checkout token via redirectUrl.
The request must include an Origin (or Referer) header that matches
an allowed, verified domain.
Authorizations:
Responses
Response samples
- 200
- 401
- 403
- 500
{- "success": true,
- "token": "string",
- "expiresIn": "1h",
- "environment": "sandbox",
- "integrationType": "frontend",
- "permissions": [
- "payment:send_otp",
- "payment:verify_otp",
- "payment:create_session",
- "product:link"
], - "modules": [
- "web",
- "cart",
- "product_item"
]
}Create a payment session (web / frontend)
Creates a payment session from the merchant storefront via the web SDK.
Requires a frontend creation SDK token from POST /v1/tokenize and a
verified merchant Origin (or Referer) header.
Product rules
- Only linked products (
{ storeCode, quantity }) are allowed. Inline products with a price are rejected — frontend integrations cannot set prices.
Customer rules
- A
customerobject may not be supplied. Frontend customers are established through OTP verification on the checkout page.
Redirect
- The response
redirectUrlincludes a session-scoped checkout token (?sdk_token=…), not the caller's creation token.
Authorizations:
Request Body schema: application/json
required | Array of objects (LinkProduct) non-empty Linked catalog products only. |
object | |
| returnUrl | string <uri> |
| cancelUrl | string <uri> |
| gateway | string (GatewayName) Enum: "paypal" "stripe" "moyasar" "myfatoorah" |
Responses
Request samples
- Payload
{- "products": [
- {
- "storeCode": "SKU-1024",
- "quantity": 1
}
], - "metadata": { },
- "gateway": "paypal"
}Response samples
- 200
- 400
- 401
- 403
- 404
{- "message": "string",
- "sessionId": "string",
- "redirectUrl": "string",
- "expiresAt": "2019-08-24T14:15:22Z",
- "status": "init",
- "amount": 0,
- "currency": "string",
- "customer": {
- "email": "string",
- "phone": "string",
- "verifiedIdentifier": "string",
- "verifiedChannel": "email",
- "locked": true
}
}Create a payment session (backend)
Creates a payment session from a merchant backend (server-to-server).
Requires a backend creation SDK token from POST /v1/auth. No
Origin header is required.
Product rules
- Linked products (
{ storeCode, quantity }) requireproduct:link. - Inline products (
{ name, price, quantity, ... }) requireproduct:create.
Customer rules
- A
customerobject may be supplied when holdingcustomer:createorcustomer:select. When provided, the resulting session has a locked, pre-verified customer.
Redirect
- The response
redirectUrlincludes a session-scoped checkout token (?sdk_token=…), not the caller's backend creation token.
Authorizations:
Request Body schema: application/json
required | Array of LinkProduct (object) or InlineProduct (object) non-empty A mix of linked and/or inline products. |
object Backend-only pre-set customer. Locks the checkout customer field. | |
object | |
| returnUrl | string <uri> |
| cancelUrl | string <uri> |
| gateway | string (GatewayName) Enum: "paypal" "stripe" "moyasar" "myfatoorah" |
Responses
Request samples
- Payload
{- "products": [
- {
- "storeCode": "SKU-1024",
- "quantity": 1
}
], - "customer": {
- "email": "user@example.com",
- "phone": "string"
}, - "metadata": { },
- "gateway": "paypal"
}Response samples
- 200
- 400
- 401
- 403
- 404
{- "message": "string",
- "sessionId": "string",
- "redirectUrl": "string",
- "expiresAt": "2019-08-24T14:15:22Z",
- "status": "init",
- "amount": 0,
- "currency": "string",
- "customer": {
- "email": "string",
- "phone": "string",
- "verifiedIdentifier": "string",
- "verifiedChannel": "email",
- "locked": true
}
}Get checkout session details
Returns the full session payload used to render the hosted checkout page.
Authenticated with the checkout token from the session's
redirectUrl (?sdk_token=…). When the token carries a sessionId
claim, it must match the requested session — a checkout token for
session A cannot read session B.
Authorizations:
path Parameters
| token required | string The payment session token. |
Responses
Response samples
- 200
- 401
- 403
- 404
{- "sessionId": "string",
- "applicationName": "string",
- "customerName": "string",
- "customer": {
- "email": "string",
- "phone": "string",
- "verifiedIdentifier": "string",
- "verifiedChannel": "email",
- "locked": true
}, - "totalAmount": 0,
- "totalTax": 0,
- "currency": "string",
- "method": "card",
- "gateway": "moyasar",
- "gatewayPublicKey": "string",
- "gatewayPublicConfigs": {
- "property1": { },
- "property2": { }
}, - "status": "init",
- "returnUrl": "string",
- "error": {
- "message": "string",
- "code": "string"
}, - "orderNumber": "string",
- "expiresAtUtc": "2019-08-24T14:15:22Z",
- "metadata": { },
- "showProducts": true,
- "showCurrencySelector": true,
- "showTaxElement": true,
- "showCustomerElement": true,
- "showAddressElement": true,
- "showShipping": true,
- "showPayment": true,
- "products": [
- {
- "sku": "string",
- "currency": "string",
- "title": "string",
- "price": 0,
- "quantity": 0,
- "imageUrl": "string",
- "productId": "string"
}
], - "brandName": "string",
- "brandLogo": "string",
- "supportedPaymentMethods": [
- "string"
], - "paymentMethodGatewayMap": {
- "property1": "string",
- "property2": "string"
}
}Send an OTP to an email or phone
Requires the session-scoped checkout token from the session
redirectUrl.
Authorizations:
Request Body schema: application/json
| method required | string Enum: "email_otp" "mobile_otp" |
| identifier required | string non-empty Email address (for |
object |
Responses
Request samples
- Payload
{- "method": "email_otp",
- "identifier": "string",
- "metadata": { }
}Response samples
- 200
- 400
- 401
- 403
{- "success": true,
- "message": "string",
- "expiresIn": 600,
- "verificationId": "string"
}Verify an OTP and obtain a payment verification token
Requires the session-scoped checkout token from the session
redirectUrl.
Authorizations:
Request Body schema: application/json
| method required | string Enum: "email_otp" "mobile_otp" |
| identifier required | string non-empty |
| code required | string non-empty |
Responses
Request samples
- Payload
{- "method": "email_otp",
- "identifier": "string",
- "code": "123456"
}Response samples
- 200
- 400
- 401
{- "success": true,
- "message": "string",
- "verificationToken": "string",
- "identifier": "string",
- "method": "email_otp",
- "expiresIn": "5m"
}Process a payment for a verified session
Charges the session. Authenticated with the payment verification
token returned by /checkout/verification/verify, passed as
Authorization: Bearer <token>.
Optionally include the other contact channel
(customerEmail / customerPhone) as supplementary data — some
gateways require a phone even when the customer verified by email.
Authorizations:
Request Body schema: application/json
| sessionToken required | string |
| method required | string |
| gateway required | string |
required | object Gateway/method specific payload. |
| customerEmail | string Supplementary email (when the customer verified by phone). |
| customerPhone | string Supplementary phone (when the customer verified by email). |
Responses
Request samples
- Payload
{- "sessionToken": "string",
- "method": "card",
- "gateway": "moyasar",
- "methodPayload": {
- "tempPaymentToken": "string",
- "clientIp": "string",
- "userAgent": "string",
- "paymentMethodId": 0,
- "type": "string"
}, - "customerEmail": "string",
- "customerPhone": "string"
}Response samples
- 200
- 400
- 403
- 404
{- "status": "init",
- "message": "string",
- "sessionId": "string",
- "paymentId": "string",
- "gateway": "string",
- "redirectUrl": "string",
- "error": {
- "code": "card_declined",
- "message": "string",
- "retryable": true,
- "details": { }
}
}Confirm a payment (deprecated) Deprecated
Deprecated. The hosted checkout now returns through
GET /payments/callback/{sessionToken}. Retained for SDK / backward
compatibility.
Authorizations:
Request Body schema: application/json
| sessionToken required | string |
Responses
Request samples
- Payload
{- "sessionToken": "string"
}Response samples
- 200
- 400
- 404
{- "status": "init",
- "message": "string",
- "sessionId": "string",
- "paymentId": "string",
- "gateway": "string",
- "redirectUrl": "string",
- "error": {
- "code": "card_declined",
- "message": "string",
- "retryable": true,
- "details": { }
}
}Gateway return callback (browser redirect)
Browser redirect target used by gateways after an off-site payment. Returns an HTML status page and then redirects to the checkout page. Not intended for programmatic use.
path Parameters
| sessionToken required | string |
query Parameters
| outcome | string Enum: "success" "cancel" |