Logo

Webhook Contract

Field-level spec for create-payment, IPN, and signature. Draft default; finalised per partner.

Status: Draft

The field-level contract below is the Bluecom-side default, derived from the NeoPay reference integration. It is the starting point for every new partner; the final shape is negotiated and frozen per provider before sandbox certification.

Create-payment request (Bluecom → Partner)

POST {ApiUrl}/<partner-create-payment-path>

FieldTypeNotes
merchantCodestringIssued by partner.
orderIdstringBluecom order reference. Unique per attempt.
amountintegerMinor units (VND has no minor units → integer dong).
currencystringISO 4217.
descriptionstringShown to the user on the hosted page.
returnUrlstringBluecom-owned; must be honoured on success and cancel.
ipnUrlstringBluecom-owned IPN endpoint.
expiresAtstring (ISO 8601)Optional; partner may enforce its own.
signaturestringHMAC-SHA256 over the ordered field list, lower-case hex.

Response (success):

{
  "providerRef": "string",
  "redirectUrl": "https://...",
  "qrPayload": "string|null",
  "expiresAt": "2026-05-13T10:15:00Z"
}

Exactly one of redirectUrl or qrPayload must be present.

IPN (Partner → Bluecom)

POST https://api.bluecom.*/api/payment/ipn

FieldTypeNotes
merchantCodestring
orderIdstringEchoes Bluecom's orderId.
providerRefstringPartner's transaction id.
statusenumSUCCESS / FAILED / EXPIRED / REFUNDED.
amountintegerMust match the create request.
currencystring
paidAtstring (ISO 8601)Required for SUCCESS.
timestampstring (ISO 8601)For replay protection. Rejected if > 5 min skew.
noncestringOptional; used if timestamp alone is insufficient.
signaturestringSame scheme as the create request.

Bluecom acknowledges with 200 OK and an empty body as soon as the signature is verified and the IPN is durably persisted to Bluecom's audit store. Order-state transition then happens asynchronously through reliable delivery; partners do not need to wait for it.

Browser return (Partner → Bluecom)

GET https://api.bluecom.*/api/payment/result?...signed-fields...

Same field set as the IPN, transported as a query string. Used only to redirect the user back to the Shop UI — never to settle an order.

Signature scheme

Default:

hex(hmac_sha256(secret, join("|", ordered_fields)))

Where ordered_fields is the lexicographic concatenation of the non-signature fields in a documented order. Partners using a different scheme (RSA, different separator, different casing) must publish the exact algorithm; Bluecom will implement against it but will not invent it.

On this page