HPP Outcomes
This page describes how to determine the final payment outcome after a customer completes (or abandons) the HPP flow.
Result Page Behaviour
After the transaction is processed, the result page behaviour depends on the resultPage value set in your Payment Request:
resultPage: "show"(default): HPP displays a hosted result page. The page shows transaction details on approval, or a decline/failure message with the option to retry (if attempts remain). WhenredirectUrlis provided, the result page includes a link back to the merchant site.resultPage: "redirect": On approved transactions, the customer is automatically redirected to the merchant’sredirectUrl. On declined or failed transactions, the hosted result page is displayed.resultPage: "none": Accepted API value.
Server-Side Reconciliation
Critical: Do not rely on the customer reaching your redirect URL to confirm payment. Always verify the outcome server-side using webhooks or polling.
Option 1: Webhooks (Recommended)
Subscribe to transactions and payment_requests webhook events. When a payment completes via HPP, you will receive:
- A transaction webhook with the transaction outcome.
- A payment request webhook with the updated
paymentRequestStatus.
For webhook setup, signing verification, and payload structure, see Webhooks.
Webhook flow:
sequenceDiagram
participant GP as Single API
participant Webhook as Your Webhook Endpoint
participant DB as Your Database
GP->>Webhook: POST callbackUrl (X-Signature + JSON payload)
Webhook->>Webhook: Verify X-Signature (HMAC-SHA256)
alt signature valid
Webhook->>Webhook: Parse event and payload
alt event = 'transactions'
Webhook->>DB: Persist transaction state
else event = 'payment_requests'
Webhook->>DB: Persist payment request state
end
Webhook->>GP: HTTP 200 OK
else signature invalid
Webhook->>GP: HTTP 401/403
end
Option 2: Polling (Fallback)
If webhooks are not available, poll the Payment Request after a reasonable delay:
GET /paymentrequests/{paymentRequestId}— checkpaymentRequestStatusand locate the transaction.GET /transactions/{transactionId}— verify final status, amount, and currency.
How to locate the transaction:
- Successful payment:
paymentRequestStatusiscompletedandtransactionResultcontains the transactionidandlocation. - Failed payment:
paymentRequestStatusiscompleted,transactionResultis not populated, andtransactionAttemptscontains the failed transaction details.
You can also retrieve transactions via GET /transactions?paymentrequestid={paymentRequestId}.
Polling flow:
sequenceDiagram
participant Server as Your Server
participant API as Single API
Server->>API: GET /paymentrequests/{paymentRequestId}
API-->>Server: Payment Request (status + transactionResult)
Server->>Server: Extract transactionId
Server->>API: GET /transactions/{transactionId}
API-->>Server: Transaction (final status, amount, codes)
Server->>Server: Verify outcome and update database
Payment Request Lifecycle
stateDiagram-v2
[*] --> created: POST /paymentrequests
created --> completed: Transaction approved or declined
created --> cancelled: Merchant cancellation
completed --> [*]
cancelled --> [*]
HPP-Specific Status Scenarios
| Scenario | What the customer sees | Payment Request status |
|---|---|---|
| Payment approved | Result page or redirect (depends on resultPage) | completed |
| Payment declined (retries remaining) | Hosted result page with retry option | Remains created |
| Payment declined (no retries) | Hosted result page — attempts exhausted | completed |
| Payment request cancelled | Hosted page indicating the request has been cancelled | cancelled |
| Payment request already completed | Redirects to the transaction result page | completed |