Prepare a crypto scenario
Create the checkout
- Authenticate with your sandbox credentials and choose the account to test.
- Register a webhook endpoint.
- Create a payment request with
CRYPTOenabled and the required payer information. UseHOSTED_PAGEorEMBEDDEDfor checkout expiry tests, and check that the response includes anexpiresAtdate and time. - Open the returned payment URL or your embedded checkout. Complete the payer steps and select the cryptocurrency and network until the deposit instructions appear. You do not need to send tokens when using the deposit simulator.
Create a new payment request for each scenario. The deposit and quote-expiry actions require a crypto quote created by checkout through Hex Trust, the crypto provider. Looking up an exchange rate alone does not create a checkout quote. The API reference uses quote round to mean all deposits linked to one checkout quote.
Capture the quote for testing
In a desktop browser, open Developer Tools → Network before selecting the cryptocurrency. Find the checkout's successful quote response containing cryptoPaymentId, cryptoQuantity and depositAddress. Save these values:
| Value | Used for |
|---|---|
Payment request id, your externalId, or paymentLinkReference | paymentRequestReference in each simulator |
Quote response cryptoPaymentId | quotePaymentId for deposits and quote expiry |
Quote response cryptoQuantity | The full amount to fund this quote, in tokens |
| A new UUID generated by your test client | depositId for one simulated transfer |
Deposit simulation response paymentId | Completion and payment lookup |
The quote ID is captured from checkout for these tests; the public rate endpoint does not supply it, and a request's payments list can be empty before a deposit. Do not build your production integration around inspecting checkout network traffic. For a mobile embedded test, capture the same response using your WebView debugging tools, or first run the scenario in a desktop browser.
Use the same quotePaymentId for every deposit for that quote. Each deposit may have a different paymentId. When checkout creates a new quote, save the values from its new response. Use the checkout response's cryptoPaymentId, not a quote ID from the crypto provider.
Send simulation requests
All examples use this sandbox base URL and headers:
curl -X POST 'https://sandbox-api.hubpay.io/v1/collections/simulate-crypto-deposit' \
-H 'Authorization: Bearer <YOUR_TOKEN>' \
-H 'AccountId: <YOUR_ACCOUNT_ID>' \
-H 'Content-Type: application/json' \
--data @deposit.json
Save the JSON request body from your chosen scenario in deposit.json. Replace the example IDs and amounts with your own values. cryptoAmount is a JSON number in the quote's cryptocurrency, with up to 18 decimal places. Keep the exact decimal value. For example, for a USDT quote, send the amount in USDT, not the invoice amount in AED. Examples using 25 assume the quote's full cryptoQuantity is exactly 25.
The endpoints accept paymentRequestId as an alias for paymentRequestReference. If your externalId matches multiple requests, use the Hubpay request UUID instead.
Retrying safely
Reuse the same depositId, quotePaymentId and amount when retrying a request or confirming a pending deposit. Generate a new deposit ID only for a new transfer. If the deposit has already reached the requested status, the response reports alreadyProcessed: true. A retry cannot change a confirmed deposit back to pending. Keep each deposit ID together with its quote ID in your test records.
A 400 response explains a validation problem, such as a closed quote, an excessive amount, an invalid expiry target or a payment that is not ready to settle. Correct the request or follow the next scenario step. A 404 indicates the requested resource was not found for the selected account. Account ownership and collections permissions still apply. If a request times out or you do not receive a response, retry with the original deposit ID or check the current status. Using a new ID would create a separate deposit.