Payment Flow — Edge Cases
Not every payment follows the happy path. This page covers non-standard outcomes — underpayment, overpayment, expiration, failed on-chain transactions, and refunds — including what Fluxis does internally, which webhooks you receive, and how to handle each scenario in your integration.
Overview
Code
| Scenario | Final status | Internal transaction | Webhook sent |
|---|---|---|---|
| Exact payment | completed → confirmed | Yes | processing, completed |
| Underpayment | underpaid | No | processing, underpaid |
| Overpayment | overpaid → confirmed | Yes (full received amount) | processing, overpaid |
| No payment in time | expired | No | No |
| On-chain tx reverts / fails | processing (stuck) | No | processing only |
Webhook delivery matrix
Fluxis sends account-level webhooks for these payment request status changes only:
| Status | Webhook delivered | Typical trigger |
|---|---|---|
processing | Yes | Cron detected on-chain transfer (hop 1) |
completed | Yes | Confirmed after finality; amount matches (hop 2) |
underpaid | Yes | Confirmed after finality; amount too low (hop 2) |
overpaid | Yes | Confirmed after finality; amount too high (hop 2) |
confirmed | No | Internal ledger transaction created (hop 3) |
expired | No | Expiration cron marks request as expired |
failed | No | Not currently set by the worker |
pending / created | No | Initial creation — poll or use your own UI state |
Poll for statuses without webhooks
Use GET /v1/pos/{posID}/payment-request/{paymentRequestID} to detect expired and confirmed states. Register webhooks at POST /v1/account/{accountID}/webhook — see Webhooks.
Underpaid
An underpaid payment occurs when the customer sends less than the expected amount and the on-chain transaction is confirmed after finality.
What Fluxis does
Code
- Hop 2 compares
ReceivedAmount(from cron detection) againstExpectedAmount - Status is set to
underpaid - A webhook is sent with status
underpaid - The vault is released and removed from Redis cache
- Hop 3 is skipped — no internal
Transactionrecord is created, status does not reachconfirmed
No ledger transaction for underpaid
Because hop 3 only runs for completed and overpaid statuses, underpaid payments remain outside the standard settlement pipeline. Coordinate resolution with Fluxis support or initiate a refund if returning funds to the customer.
Merchant handling
| Action | Recommendation |
|---|---|
| Do not fulfill the order automatically | Treat underpaid as a partial payment requiring manual review |
| Contact the customer | Request the remaining balance or agree on a partial fulfillment |
| Create a new payment request | For the outstanding difference, if the customer agrees to pay more |
| Request a refund | Use the Refunds API to return the partial amount to the customer's wallet |
Eligible refund statuses include underpaid. See Refunds API below.
Overpaid
An overpaid payment occurs when the customer sends more than the expected amount.
What Fluxis does
Code
- Hop 2 sets status to
overpaidand records the full received amount - A webhook is sent with status
overpaid - Hop 3 creates an internal Transaction for the full received amount
- Status transitions to
confirmed(no additional webhook)
Merchant handling
| Action | Recommendation |
|---|---|
| Fulfill the order for the requested amount | The customer paid at least the expected price |
| Refund the excess | Use POST /v1/refunds/payment-request/{paymentRequestID} with an explicit amount for the overpaid portion |
| Contact support | For complex cases where automatic refund is insufficient |
When amount is omitted on a refund request for an overpaid payment, Fluxis defaults to refunding the overpaid portion (received minus expected).
Expired
A payment request expires when no on-chain payment is detected before the expiration timestamp.
Timing
| Setting | Value | Scope |
|---|---|---|
| Payment request expiration | 8 minutes | From vault assignment (created status) |
| Payment intention expiration | 5 minutes | Cashier PoS flow only, before PR creation |
| Expiration check interval | Every 30 seconds | Background cron job |
What Fluxis does
Code
- The expiration cron finds payment requests with
status = createdandexpiration < now - Updates status to
expired - No webhook is sent for expiration
- The vault is not immediately released — it is recycled when the vault pool reassigns it (expired vault overwrite logic)
Grace period for late payments
Transactions broadcast just before expiration may still be detected if the vault address remains in the Redis cache (TTL = expiration + 60 seconds). Do not assume expired means the customer cannot pay — check for late-arriving processing webhooks or poll the status endpoint.
Merchant handling
| Action | Recommendation |
|---|---|
| Show expiration in UI | Display a countdown based on the expiration field from the create response |
| Create a new payment request | Standard recovery — each request is single-use |
| Poll for late payments | If a customer claims they paid, check status before creating a duplicate request |
See Payment Requests — Timing for details.
Failed transaction stuck in processing
When an on-chain transaction fails or reverts after being detected, the worker logs the failure but does not update the payment request status.
What Fluxis does
In hop 2 (transaction_check_update_payment_request), when GetTransaction returns a failed status:
- The worker logs
"Blockchain Transaction Failed" - Returns without updating the payment request
- The payment request remains in
processingindefinitely - No additional webhook is sent beyond the initial
processingnotification
Code
Known behavior
This is current platform behavior. If a payment request is stuck in processing and the on-chain transaction has failed, contact [email protected] for manual resolution. Poll GET /v1/pos/{posID}/payment-request/{paymentRequestID} and verify the transaction hash on a block explorer.
Merchant handling
| Action | Recommendation |
|---|---|
| Verify on-chain | Look up the transaction hash (if available) on a block explorer |
| Do not fulfill | A stuck processing status does not guarantee payment |
| Contact support | Provide the payment request ID and transaction hash |
| Create a new payment request | If the original transaction definitively failed |
Refunds API
Fluxis provides a Refunds API to initiate refunds for eligible payment requests. Refunds are created at the API level and trigger a webhook notification — on-chain refund execution is not yet automated.
Eligible statuses
Refunds can be created when the payment request is in one of:
completedconfirmedoverpaidunderpaid
Create a refund
Code
Code
| Field | Required | Description |
|---|---|---|
refund_to_address | Yes | Customer wallet address to receive the refund |
amount | No | Amount to refund. If omitted: full amount for completed/confirmed, overpaid portion for overpaid |
reason | No | Free-text reason for audit trail |
Example response:
Code
Check refund status
Code
Refund webhook
When a refund is created, Fluxis sends a webhook with notification_type: refund_status_update:
Code
On-chain execution pending
The refund API creates a processing record and sends a webhook. Actual on-chain refund transaction processing is planned but not yet automated. Treat refund records as intent until refund_transaction_hash is populated on GET /v1/refunds/{refundID}.
Common refund scenarios
| Scenario | Suggested approach |
|---|---|
| Overpaid | Omit amount to refund the excess, or specify the exact overpaid portion |
| Underpaid — return partial payment | Specify amount equal to the received (partial) amount |
| Completed — full refund | Omit amount to refund the full payment |
| Customer provided wrong address | Contact support if the refund address needs correction after submission |
Integration checklist for edge cases
Use this checklist when building production integrations:
Code
- Handle all four webhook statuses —
processing,completed,underpaid,overpaid - Never fulfill on
processing— wait for a terminal amount outcome - Poll for
expiredandconfirmed— these do not trigger webhooks - Display the 8-minute countdown — reduce expired-payment support tickets
- Verify webhook signatures — see Webhook Signature Verification
- Use the Refunds API for overpaid/underpaid resolution where appropriate
- Monitor stuck
processing— check block explorer if status does not progress
Related documentation
- Payment Flow — Happy Path — Standard create → detect → confirm flow
- Payment Requests — State definitions and API examples
- Creating Payment Requests — Integration guide
- Webhooks — Registration and payload format
- Webhook Signature Verification — HMAC verification and test workflow
- FAQ — Payment Monitoring — Common questions
- API Reference — Refunds — Interactive endpoint documentation