TPI Pay
Payment integration

TPIPAY API integration

Forward a payment request, redirect the customer to the secure checkout, and verify the resulting transaction.

Sandbox/Test mode documentation is derived from the current project implementation in the sandbox API routes, middleware, controller, and seeded scenario data. No live API behavior or production routes were changed.

Copy-paste cURL (Sandbox / Test Mode)

Use these exact headers and payloads in Postman. This matches the project’s sandbox API implementation.

curl --location --request POST 'https://staging.login.tpipay.ai/api/sandbox/payment' \ --header 'X-API-KEY: pk_test_XXXXXXXX' \ --header 'Authorization: sk_test_XXXXXXXX' \ --header 'Content-Type: application/json' \ --data '{ "amount": 1500.00, "currency": "INR", "customer_name": "Raj Sharma", "customer_phone": "9876543210", "customer_email": "raj@example.com", "transaction_id": "ORD-SANDBOX-1001", "description": "Sandbox payment test", "success_url": "https://yourdomain.com/payment/success", "failure_url": "https://yourdomain.com/payment/failure", "cancel_url": "https://yourdomain.com/payment/cancel", "webhook_url": "https://yourdomain.com/webhook", "payment_method": "UPI" }'

Sandbox status check

curl --location --request GET 'https://staging.login.tpipay.ai/api/sandbox/payments-status/ORD-SANDBOX-1001' \ --header 'X-API-KEY: pk_test_XXXXXXXX' \ --header 'Authorization: sk_test_XXXXXXXX'

Sandbox base URL

Use the sandbox/test environment for merchant API testing. The current application exposes sandbox endpoints under the API prefix.

Base URL: /api
Endpoint Method Purpose
/api/sandbox/payment POST Create a sandbox payment.
/api/sandbox/payments-status/{transactionId} GET Current transaction status route defined in the sandbox API.
/sandbox/checkout/{token}/status GET Sandbox checkout status endpoint used by the checkout page.

Sandbox authentication

The sandbox API authenticates using merchant API credentials generated for the test environment.

Header Example Description
X-API-KEY pk_test_XXXXXXXX Merchant API key for the sandbox/test environment.
X-API-SECRET sk_test_XXXXXXXX Merchant API secret for the sandbox/test environment. Authorization: Bearer <api_secret> is also accepted.
Authorization Bearer sk_test_XXXXXXXX Alternative to X-API-SECRET.

Example request headers

{
  "X-API-KEY": "pk_test_XXXXXXXX",
  "X-API-SECRET": "sk_test_XXXXXXXX",
  "Content-Type": "application/json",
  
}

Credential generation is handled by the existing merchant API credential service, which stores api_key and a hashed secret for the selected test environment. The code checks MerchantApiCredential::where('environment', 'test') and validates the secret using Laravel Hash.

Create sandbox payment

Creates a sandbox payment record and returns a checkout URL for the sandbox checkout flow.

POST: /api/sandbox/payment
Field Type Required Description
transaction_id string No Custom transaction reference. If omitted, the app creates one automatically.
amount numeric Yes Amount in rupees, accepted as a decimal; minimum 0.01 and maximum 100000000.
currency string No Must be INR.
customer_name string Yes Customer name.
customer_email string No Valid email.
customer_phone string Yes Customer mobile number.
description string No Payment description.
success_url string No Optional success redirect URL.
failure_url string No Optional failure redirect URL.
cancel_url string No Optional cancel redirect URL.
webhook_url string No Optional webhook callback URL.
gateway string No Optional gateway name field.
idempotency_key string No
payment_method string No Allowed: UPI, CARD, NET_BANKING, EMI, WALLET, PAY_LATTER.

Example request

{
  "amount": 1500.00,
  "currency": "INR",
  "customer_name": "Raj Sharma",
  "customer_phone": "9876543210",
  "customer_email": "raj@example.com",
  "transaction_id": "ORD-SANDBOX-1001",
  "description": "Sandbox payment test",
  "success_url": "https://yourdomain.com/payment/success",
  "failure_url": "https://yourdomain.com/payment/failure",
  "webhook_url": "https://yourdomain.com/webhook"
}

Example response

{
  "success": true,
  "message": "Sandbox payment created successfully.",
  "data": {
    "payment_id": 123,
    "transaction_id": "ORD-SANDBOX-1001",
    "amount": "1500.00",
    "status": "created",
    "environment": "sandbox",
    "checkout_url": "https://login.tpipay.ai/sandbox/checkout/abcd1234"
  }
}

Sandbox test scenarios

These scenarios are seeded in the project and are used by the sandbox checkout screen and simulator. They are the actual values currently supported by the application.

Method Scenario Result Inputs
UPI UPI_SUCCESS success success@tpipay
UPI UPI_FAILED failed failure@tpipay
UPI UPI_PENDING pending pending@tpipay
CARD CARD_SUCCESS success 4111111111111111, expiry 12/30, CVV 123
CARD CARD_FAILED failed 4000000000000002, expiry 12/30, CVV 123
CARD CARD_PENDING pending 4000000000009995, expiry 12/30, CVV 123
NET_BANKING NB_SUCCESS success Bank TPITEST, username testuser, password test123
NET_BANKING NB_FAILED failed Bank TPITEST, username faileduser, password failed123
WALLET WALLET_SUCCESS success Wallet TPITESTWALLET, mobile 9999999999, OTP 123456
WALLET WALLET_FAILED failed Wallet TPITESTWALLET, mobile 9999999998, OTP 000000
EMI EMI_SUCCESS success Card 4111111111111111, tenure 6, CVV 123
EMI EMI_FAILED failed Card 4000000000000002, tenure 6, CVV 123
PAY_LATTER PAY_LATER_SUCCESS success Provider TPIPAY_LATER, mobile 9999999999, OTP 123456
PAY_LATTER PAY_LATER_FAILED failed Provider TPIPAY_LATER, mobile 9999999998, OTP 000000

Sandbox status

The app includes a sandbox checkout status endpoint that returns current payment state for a checkout token.

GET: /sandbox/checkout/{token}/status

Example response

{
  "success": true,
  "message": "Payment status retrieved successfully.",
  "data": {
    "transaction_id": "ORD-SANDBOX-1001",
    "payment_id": 123,
    "currency": "INR",
    "amount": "1500.00",
    "status": "pending",
    "payment_method": "UPI",
    "paid_at": null,
    "environment": "sandbox",
    "success_url": "https://yourdomain.com/payment/success",
    "failure_url": "https://yourdomain.com/payment/failure",
    "cancel_url": "https://yourdomain.com/payment/cancel",
    "webhook_url": "https://yourdomain.com/webhook"
  }
}

There is also a direct sandbox status route defined as /api/sandbox/payments-status/{transactionId}, but in the current code it is still a debug handler that dumps request data and is not the stable, browser-facing status endpoint. The checkout-token route is the implemented, tested status route used by the sandbox checkout flow.

Sandbox callback / webhook

The sandbox simulator dispatches a webhook payload when the status transitions to a terminal state. This is the implemented behavior from the queue jobs and simulator.

Field Type Description
event string payment.updated
payment_id integer Local payment ID.
transaction_id string Merchant transaction ID.
amount string Amount formatted to 2 decimal places.
currency string Defaults to INR.
status string Final status: success, failed, or cancelled.
environment string sandbox
payment_method string Payment method selected in the test scenario.

Example webhook payload

{
  "event": "payment.updated",
  "payment_id": 123,
  "transaction_id": "ORD-SANDBOX-1001",
  "amount": "1500.00",
  "currency": "INR",
  "status": "success",
  "environment": "sandbox",
  "payment_method": "UPI"
}

Sandbox error handling

The sandbox API returns structured JSON error payloads when authentication fails, credentials are missing, the merchant is invalid, or validation fails.

Code Meaning Example
INVALID_SANDBOX_CREDENTIALS Authentication failed or invalid credentials. { "success": false, "message": "Sandbox authentication failed.", "error_code": "INVALID_SANDBOX_CREDENTIALS" }
SANDBOX_CREDENTIALS_NOT_CONFIGURED No active sandbox credential exists. { "success": false, "message": "Sandbox credentials are not configured.", "error_code": "SANDBOX_CREDENTIALS_NOT_CONFIGURED" }
SANDBOX_CREDENTIALS_INACTIVE Credential exists but disabled. { "success": false, "message": "Sandbox credentials are inactive.", "error_code": "SANDBOX_CREDENTIALS_INACTIVE" }
PAYMENT_NOT_FOUND Requested checkout token or transaction was not found. { "success": false, "message": "Payment not found.", "error_code": "PAYMENT_NOT_FOUND" }
TRANSACTION_ID_ALREADY_EXISTS Duplicate transaction ID. { "success": false, "message": "Transaction ID already exists.", "error_code": "TRANSACTION_ID_ALREADY_EXISTS" }

Seamless Integration

Use the Seamless API when you want to create a payment request directly from your backend with a bearer token, without sending the customer through the merchant forwarding flow first. The route structure reuses the existing payment creation logic and the merchant-level method configuration.

The Seamless API is additive and does not change the existing Hosted Checkout or Non-Seamless flows. It is intended for merchants who already have merchant API credentials and want a token-based protected endpoint for backend-driven payment initiation.

Supported Seamless methods currently documented here are UPI and CARD. Wallet and Netbanking are kept as landing pages for now so you can expand them later without disturbing the main menu structure.

Issue a Seamless access token

Create a short-lived bearer token for the protected Seamless payment and ping endpoints.

POST: https://staging.login.tpipay.ai/api/v1/pg/token

Request data

Headers

HeaderValueDescription
X-API-KEYyour-api-keyMerchant API key for the selected environment.
Authorizationyour-api-secretMerchant API secret. Authorization: Bearer your-api-secret may also be used.
Content-Typeapplication/jsonSend the request body as JSON.
JSON headers
{
  "X-API-KEY": "your-api-key",
  "Authorization": "your-api-secret",
  "Content-Type": "application/json"
}

Body

FieldTypeRequiredDescription
scopesarrayNoOptional scopes to limit the token. Currently supported scopes are used for payment creation and ping access.
scopes.*stringNoIndividual scope name, for example payments:create.
environmentstringNoEnvironment to issue the token for: live or test.

Example request

{
  "scopes": ["payments:create"],
  "environment": "test"
}
Success response

Verify Seamless token access

Use the ping endpoint to verify that the bearer token is valid and that the merchant context is correctly attached.

GET: https://staging.login.tpipay.ai/api/v1/pg/ping

Request data

Headers

HeaderValueDescription
AuthorizationBearer <seamless_token>Seamless bearer token returned by the token endpoint.
X-Seamless-Signatureoptional-hmac-signatureOptional signature header when you want to verify the request payload using your merchant webhook secret.
JSON headers
{
  "Authorization": "Bearer <seamless_token>",
  "X-Seamless-Signature": "<optional-hmac-signature>"
}

Example request

GET <?php echo e($apiBaseUrl); ?>/api/v1/pg/ping
Success response

UPI Integration

Use the Seamless API with the UPI payment method to create a payment request directly from your server. The request uses the bearer token returned in the token endpoint and the same merchant payment fields already used by the existing Merchant Payment API.

curl --location --request POST 'https://staging.login.tpipay.ai/api/v1/pg/payments' \ --header 'Authorization: Bearer ' \ --header 'Content-Type: application/json' \ --header 'X-Seamless-Signature: ' \ --data '{ "amount": 1500.00, "currency": "INR", "customer_name": "Raj Sharma", "customer_phone": "9876543210", "customer_email": "raj@example.com", "transaction_id": "ORD-SEAMLESS-UPI-001", "description": "Seamless UPI payment", "success_url": "https://yourdomain.com/payment/success", "failure_url": "https://yourdomain.com/payment/failure", "cancel_url": "https://yourdomain.com/payment/cancel", "webhook_url": "https://yourdomain.com/webhook", "payment_method": "UPI" }'

UPI request fields

All basic payment fields are the same as the existing Merchant Payment API. For Seamless, the important difference is that the token is sent in the Authorization header instead of merchant API credentials in each request.

POST: https://staging.login.tpipay.ai/api/v1/pg/payments

Request data

Headers

HeaderValueDescription
AuthorizationBearer <seamless_token>Seamless bearer token returned by the token endpoint.
Content-Typeapplication/jsonSend the request body as JSON.
X-Seamless-Signatureoptional-hmac-signatureOptional signature that matches the request payload using your merchant webhook secret.

Body

FieldTypeRequiredDescription
amountnumericYesAmount in rupees; minimum 0.01 and maximum 100000000.
currencystringNoMust be INR; defaults to INR.
customer_namestringYesCustomer name.
customer_phonestringYesCustomer mobile number.
customer_emailstringNoValid customer email.
transaction_idstringNoYour unique reference. If omitted, the app creates one automatically.
descriptionstringNoPayment description.
success_urlstringNoOptional success redirect URL.
failure_urlstringNoOptional failure redirect URL.
cancel_urlstringNoOptional cancel redirect URL.
webhook_urlstringNoOptional webhook URL for status updates.
gatewaystringNoOptional gateway override if you want to target a specific configured gateway.
idempotency_keystringNoOptional retry-safe key.
payment_methodstringYesMust be UPI for this integration.

Example request

{
  "amount": 1500.00,
  "currency": "INR",
  "customer_name": "Raj Sharma",
  "customer_phone": "9876543210",
  "customer_email": "raj@example.com",
  "transaction_id": "ORD-SEAMLESS-UPI-001",
  "description": "Seamless UPI payment",
  "success_url": "https://yourdomain.com/payment/success",
  "failure_url": "https://yourdomain.com/payment/failure",
  "cancel_url": "https://yourdomain.com/payment/cancel",
  "webhook_url": "https://yourdomain.com/webhook",
  "payment_method": "UPI"
}
Success response

Card Integration

Use the same Seamless payment endpoint with payment_method set to CARD. The backend uses the merchant’s configured payment gateway and method permissions, then returns the checkout or redirect URL produced by that gateway.

curl --location --request POST 'https://staging.login.tpipay.ai/api/v1/pg/payments' \ --header 'Authorization: Bearer ' \ --header 'Content-Type: application/json' \ --header 'X-Seamless-Signature: ' \ --data '{ "amount": 1500.00, "currency": "INR", "customer_name": "Raj Sharma", "customer_phone": "9876543210", "customer_email": "raj@example.com", "transaction_id": "ORD-SEAMLESS-CARD-001", "description": "Seamless card payment", "success_url": "https://yourdomain.com/payment/success", "failure_url": "https://yourdomain.com/payment/failure", "cancel_url": "https://yourdomain.com/payment/cancel", "webhook_url": "https://yourdomain.com/webhook", "payment_method": "CARD" }'

Card request fields

The Seamless Card flow uses the same request envelope as the generic Seamless payment request. The chosen gateway handles the actual card checkout experience and the returned payment details.

POST: https://staging.login.tpipay.ai/api/v1/pg/payments

Request data

Headers

HeaderValueDescription
AuthorizationBearer <seamless_token>Seamless bearer token for the merchant and environment.
Content-Typeapplication/jsonSend the request body as JSON.
X-Seamless-Signatureoptional-hmac-signatureOptional request signature header using the merchant webhook secret.

Body

FieldTypeRequiredDescription
amountnumericYesAmount in rupees; minimum 0.01 and maximum 100000000.
currencystringNoMust be INR; defaults to INR.
customer_namestringYesCustomer name.
customer_phonestringYesCustomer mobile number.
customer_emailstringNoValid customer email.
transaction_idstringNoYour unique reference. If omitted, the app creates one automatically.
descriptionstringNoPayment description.
success_urlstringNoOptional success redirect URL.
failure_urlstringNoOptional failure redirect URL.
cancel_urlstringNoOptional cancel redirect URL.
webhook_urlstringNoOptional webhook URL for status updates.
gatewaystringNoOptional gateway override if you want to target a specific configured gateway.
idempotency_keystringNoOptional retry-safe key.
payment_methodstringYesMust be CARD for this integration.

Example request

{
  "amount": 1500.00,
  "currency": "INR",
  "customer_name": "Raj Sharma",
  "customer_phone": "9876543210",
  "customer_email": "raj@example.com",
  "transaction_id": "ORD-SEAMLESS-CARD-001",
  "description": "Seamless card payment",
  "success_url": "https://yourdomain.com/payment/success",
  "failure_url": "https://yourdomain.com/payment/failure",
  "cancel_url": "https://yourdomain.com/payment/cancel",
  "webhook_url": "https://yourdomain.com/webhook",
  "payment_method": "CARD"
}
Success response

Wallet Integration

Wallet integration is reserved as a landing page for now. The Seamless menu entry is already in place, but the full wallet implementation and detailed documentation will be added in a later update.

This section is intentionally left as a placeholder. When wallet support is ready, it will follow the same structure as UPI and Card with cURL, request headers, field details, and response examples.

Netbanking Integration

Netbanking integration is also kept as a landing page for now. The Seamless menu item is ready, and the full details can be added later without changing the current API structure.

This section currently acts as a placeholder. Once the Netbanking flow is finalized, you can expand it with the same endpoint pattern, headers, request fields, and response examples used in the UPI and Card docs.