1. Prerequisites: no identity documents required
An initial inquiry and review of technical requirements do not require an ID card, passport, business registration certificate, or copy or photo of those documents. Share only the following business and technical information:
- Business type, users and transaction scenarios
- Operating regions and target market
- Expected daily and monthly counts, value ranges, peaks and currencies
- Collection, refund, payout, settlement and reconciliation requirements
- Technical architecture, callback domains and API requirements
- Technical contacts, production-change process and emergency arrangements
The fact that no identity documents are required for an initial inquiry does not mean that a production channel, limit or settlement condition has been approved. Those conditions still require business and channel review and written confirmation.
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 |
This page makes no assumption that a processor provides these fields, names or fee definitions. Obtain a sample reconciliation file and data dictionary before testing.
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.
Before integration, review the actual service boundaries and obtain written confirmation of the current documentation version, production domains, credential-delivery method, settlement rules and exception contacts.
Review service boundaries