API integration guide

Payment API structure example

This guide explains API orders, signatures, callbacks, queries, recovery, errors and reconciliation. Fields, statuses and algorithms are structural examples; actual integration details follow the applicable technical documentation.

Every field and URL is a structural example, not a production credential. api.example-processor.test and all other example domains, merchant IDs, order IDs, signatures and key placeholders are reserved non-production examples and cannot be used for real transactions. Production parameters must come from the formal technical specification and a secure credential-delivery process.

1. Quick start

This public structure covers the common API integration flow:

  • Order creation and response structure
  • Signatures and credential security
  • Asynchronous callbacks and verification
  • Order queries and status updates
  • Failure handling and recovery
  • Reconciliation and settlement records

Production fields, credentials and channel parameters follow the formal technical documentation.

2. Create an order: request and response

Represent amounts as fixed-point decimal strings where required, and keep merchant order IDs unique within the merchant scope. Do not infer that an actual API necessarily contains any field shown here.

Example request

POST https://api.example-processor.test/v1/orders
Content-Type: application/json
X-Merchant-Id: merchant_demo_001
X-Timestamp: 1784851200
X-Nonce: nonce_7f3a9c
X-Signature: SIGNATURE_PLACEHOLDER

{
  "merchant_order_id": "ORDER_20260724_0001",
  "amount": "1250.00",
  "currency": "PHP",
  "payment_method": "WALLET_OR_QR_EXAMPLE",
  "callback_url": "https://merchant.example.test/webhooks/payments",
  "return_url": "https://merchant.example.test/orders/ORDER_20260724_0001",
  "description": "Example order"
}

Example response

{
  "request_id": "req_demo_a81f",
  "processor_order_id": "pay_demo_92831",
  "merchant_order_id": "ORDER_20260724_0001",
  "status": "PENDING",
  "amount": "1250.00",
  "currency": "PHP",
  "payment_url": "https://checkout.example-processor.test/pay/pay_demo_92831",
  "expires_at": "2026-07-24T16:30:00Z"
}
Conceptual fieldPurposeImplementation note
merchant_order_idMerchant-side order identifierUsed for idempotency, queries and reconciliation; confirm uniqueness rules in writing
processor_order_idProcessor-side order identifierStore it alongside the merchant order ID; do not overwrite either value
payment_urlExample checkout addressRedirect only to a confirmed domain and validate its expiry

3. Signing strings, callback verification and idempotency

This pseudocode only illustrates signing a canonicalized request. The actual algorithm may differ. Confirm the raw body, character encoding, line breaks, field order, digest format, time window and key version.

canonicalBody = SHA256(rawRequestBody)
canonicalString = HTTP_METHOD + "\n"
  + REQUEST_PATH + "\n"
  + TIMESTAMP + "\n"
  + NONCE + "\n"
  + canonicalBody

signature = HEX(HMAC_SHA256(secret, canonicalString))

// The actual documentation governs the algorithm, field order, encoding,
// letter case and handling of empty values.

Example callback payload

{
  "event_id": "evt_demo_4012",
  "event_type": "payment.status_changed",
  "created_at": "2026-07-24T16:12:03Z",
  "data": {
    "processor_order_id": "pay_demo_92831",
    "merchant_order_id": "ORDER_20260724_0001",
    "status": "SUCCEEDED",
    "amount": "1250.00",
    "currency": "PHP",
    "paid_at": "2026-07-24T16:12:01Z"
  }
}
  1. Verify first: use the received raw request body and agreed headers, validate timestamp and nonce, and reject expired or incorrectly signed requests.
  2. Apply idempotency: atomically store a confirmed unique event_id or order-and-status version. Return the agreed success response for duplicate events without posting twice.
  3. Then update: lock the order and validate amount, currency and permitted status transition. A callback synchronizes status; ledger changes belong in the same transaction or a recoverable process.
  4. Keep an audit trail: record request ID, event ID, verification result, old and new status, and processing time. Never log keys or complete sensitive values.

4. Order state machine, active queries and recovery

PENDING

Awaiting payment or processing

PROCESSING

Result is not yet final

SUCCEEDED

Example terminal state: payment succeeded

FAILED / EXPIRED

Example terminal state: failed or expired

Status names and terminal-state definitions are examples. Permit transitions only when written documentation allows them, and never let a late processing callback overwrite a successful terminal state.

Query and recovery recommendations

  • When a callback times out, fails verification or leaves an order processing too long, use the agreed query API. Do not post funds based on a browser redirect.
  • Use backoff, jitter and a frequency cap for queries, and retain each request ID to avoid concentrated polling.
  • Recovery is an audited status-verification process, not unconditional order recreation or duplicate payment.
  • Manual corrections require two-person review and a record of evidence, operator, time, original status and target status.

5. Error responses and reconciliation fields

HTTP/1.1 422 Unprocessable Entity
Content-Type: application/json

{
  "request_id": "req_demo_f018",
  "error": {
    "code": "INVALID_PARAMETER_EXAMPLE",
    "message": "Request validation failed",
    "field": "amount"
  }
}

Classify handling by HTTP status, business error code and request ID. Retry with backoff only for timeouts or server errors identified as retryable in writing; do not blindly retry parameter, authentication, balance or limit results.

Conceptual fields to reconcile

GroupStructure exampleReconciliation purpose
Ordermerchant_order_id, processor_order_idMap orders between the parties
Amountgross_amount, fee_amount, net_amount, currencyCheck order, fee and net-amount definitions
Statusstatus, paid_at, completed_atCheck terminal state and business-date boundaries
Settlementsettlement_id, settlement_date, settlement_statusLink batches to written settlement rules

Actual reconciliation fields, names and fee definitions follow the applicable technical documentation.

6. Launch test matrix and key security

Test areaMinimum coverageAcceptance evidence
Order outcomesSuccess, failure, expiry, processing, user cancellationOrder record, callback and query agree
Notification exceptionsDuplicate, out-of-order, delayed, invalid signature, timeout retryIdempotency records and transition logs
Amount boundariesMinimum, maximum, decimal places, currency, mismatchRejection rules and reconciliation results
Query and recoveryMissing callback, prolonged processing, terminal-state queryBackoff policy and audit records
Settlement reconciliationCross-day, fees, net amounts, differences, batchesSigned or written acceptance conclusion

Key-security baseline

  • Separate test and production keys. Inject them through a controlled secrets manager, never source code, chat, ticket screenshots or frontend bundles.
  • Apply least privilege by credential purpose and environment. Audit creation, viewing, rotation, revocation and unusual access.
  • Support key versions and an overlapping rotation window. Revoke exposed keys immediately and review logs, orders and callbacks.
  • Use TLS, request-size limits and rate limits on callback endpoints. An IP allowlist is only an additional control and cannot replace signature verification.

For production integration, use the agreed documentation version, production domains, credential-delivery method, settlement rules and exception contacts.

View service boundaries
Contact payment support