Full and Partial Refunds
Overview
Refunding transactions is a crucial aspect of managing a successful merchant operation. CrissCross supports both full and partial refunds, allowing merchants to process refunds directly through the same payment rails used for the original transactions.
How CrissCross Executes Refunds
You always call the same POST /payment/refunds endpoint, but under the hood CrissCross executes a refund in one of two ways depending on what the originating payment provider supports:
- Provider refund. When the originating provider exposes a refund API, CrissCross calls it directly. This is the preferred path because it reverses the original movement on the rail it came in on.
- Payout refund. When the originating provider does not support refunds, CrissCross automatically converts the refund into a payout back to the original destination (the payer’s mobile wallet, bank account, etc.). This is particularly common for mobile money, where many providers expose payouts but not refund APIs, and is also used for bank payment methods when we hold the full destination account details.
Two practical consequences:
- No time limit on payout refunds. Provider refund windows (typically 90–180 days, sometimes shorter) only apply when CrissCross takes the provider-refund path. Payout refunds can be issued whenever the destination is still valid.
- Unified accounting. Both types are tracked as refunds against the original transaction (they appear in
refundTransactionIdsand contribute tototalRefundedValueon the session). You cannot over-refund a customer regardless of which mechanism executes, because the same balance is enforced for both.
The mechanism CrissCross chose for any given refund is visible on the returned refund transaction; consumers do not need to differentiate between the two paths to issue or track refunds correctly.
Refund Requirements
- Available Balances: To process refunds, merchants must maintain sufficient balances with their payment processors in the relevant markets. Payout refunds additionally require sufficient payout balance for the destination currency.
- Transaction Eligibility: Refunds can only be issued against transactions that have been successfully captured and settled. Provider-refund windows apply only on the provider-refund path; payout refunds are not subject to a CrissCross-imposed time limit.
Creating a Refund
Refunds are created against a checkout session using POST /payment/refunds. The request body takes:
sessionId— the session whose transaction you want to refund.refundValue— an object withminorAmount(the refund amount in minor units, e.g. cents) andcurrency(ISO 4217). The currency must match the original transaction. This mirrors thedestinationValueshape used on payouts.originalTransactionId(optional) — only needed when a session has more than one refundable transaction. If omitted, CrissCross resolves to the single refundable transaction on the session.reason(optional) — free-form note recorded for reporting and dispute defense.
A refund is itself a transaction in CrissCross, so the response follows the same shape as other transaction responses: transactionId, status, and message, plus refund-specific fields:
transactionId— the refund’s own transaction identifier. Use this to retrieve the refund or correlate webhook events.originalTransactionId— the transaction on the session that was refunded. Returned even when the request omitted it, so callers can see which transaction was selected.sessionIdandrefundValue— echoed back from the request.
Refunds Are Asynchronous
Refund creation always returns a record with status: PENDING. The refund is then processed against the underlying rail and transitions to COMPLETED or FAILED. There are two ways to observe the transition:
- Poll
GET /payment/refunds/{transactionId}using the returnedtransactionId. - Subscribe to the
refund.succeededandrefund.failedwebhook events.
Full Refund
A full refund returns the entire remaining refundable balance. Pass the original transaction amount in refundValue.minorAmount:
Partial Refund
Partial refunds return only a portion of the transaction amount, useful for partial returns or post-purchase discounts. Pass the partial amount in refundValue.minorAmount:
Disambiguating Multiple Transactions
If a session has more than one refundable transaction (for example, a retry that captured separately, or a split tender), the API returns 409 and requires originalTransactionId:
Retrieving a Refund
Use GET /payment/refunds/{transactionId} with the transactionId returned from creation to check the current status. The response shape matches the create response, with status reflecting the latest state (PENDING, COMPLETED, or FAILED).
Where Refunds Surface on Other Objects
Refunds are linked back from the records they affect so you don’t have to query refunds separately to understand the state of a session or transaction:
- On the parent transaction:
refundTransactionIdsis a list of thetransactionIdof every refund processed against that transaction. Pass any of them directly toGET /payment/refunds/{transactionId}. - On the session:
totalRefundedValueis a{ minorAmount, currency }object reflecting the cumulative amount refunded across all refunds on the session. Use this to check remaining refundable balance before issuing further partial refunds.
Refund Notifications
When refunds are processed, CrissCross can trigger notifications for:
- Successful Refunds: Confirmations sent to both merchants and customers.
- Balance Alerts: Notifications for top-ups when balances with processors are insufficient to cover the refund.
Best Practices
- Maintain Adequate Balances: Regularly monitor and top up your balances with payment processors to ensure smooth refund transactions.
- Communicate with Customers: Keep customers informed about the status of their refunds to maintain trust and satisfaction.
- Monitor Refund Trends: Analyze refund patterns to identify potential issues with products or services early on.
Conclusion
Efficiently managing refunds is essential for maintaining customer satisfaction and operational compliance. CrissCross provides robust tools to handle full and partial refunds, ensuring merchants can manage their financial transactions effectively.