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 field | Purpose | Implementation note |
|---|---|---|
| merchant_order_id | Merchant-side order identifier | Used for idempotency, queries and reconciliation; confirm uniqueness rules in writing |
| processor_order_id | Processor-side order identifier | Store it alongside the merchant order ID; do not overwrite either value |
| payment_url | Example checkout address | Redirect 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"
}
}- Verify first: use the received raw request body and agreed headers, validate timestamp and nonce, and reject expired or incorrectly signed requests.
- Apply idempotency: atomically store a confirmed unique
event_idor order-and-status version. Return the agreed success response for duplicate events without posting twice. - 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.
- 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
| Group | Structure example | Reconciliation purpose |
|---|---|---|
| Order | merchant_order_id, processor_order_id | Map orders between the parties |
| Amount | gross_amount, fee_amount, net_amount, currency | Check order, fee and net-amount definitions |
| Status | status, paid_at, completed_at | Check terminal state and business-date boundaries |
| Settlement | settlement_id, settlement_date, settlement_status | Link 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 area | Minimum coverage | Acceptance evidence |
|---|---|---|
| Order outcomes | Success, failure, expiry, processing, user cancellation | Order record, callback and query agree |
| Notification exceptions | Duplicate, out-of-order, delayed, invalid signature, timeout retry | Idempotency records and transition logs |
| Amount boundaries | Minimum, maximum, decimal places, currency, mismatch | Rejection rules and reconciliation results |
| Query and recovery | Missing callback, prolonged processing, terminal-state query | Backoff policy and audit records |
| Settlement reconciliation | Cross-day, fees, net amounts, differences, batches | Signed 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