- Create a dispute by submitting an API request or by using the Marqeta Dashboard, upload supporting documents, and prepare it for chargeback submission to the card network.
- Submit a dispute for chargeback and manually transition card network states as they occur in a production environment.
This guide uses a minimal configuration Mastercard cleared transaction as an example.
Prerequisites
Before you initiate the dispute process, ensure that you have the following in place:- A cleared transaction
- A webhook handler
For more information about setting up a webhook handler, see Set Up a Webhook Handler.
Dispute state flow
A Marqeta state is assigned when a dispute is first created, and a card network state is assigned when the dispute is submitted to the card network. The states transition as a dispute progresses towards resolution. The sandbox does not connect to the card networks. However, in production, you will use theDISPUTE value in the type field for integrated network disputes, and LEGACY_DISPUTE for non-integrated cases.
In production, Marqeta handles all network-side state transitions once a chargeback is submitted.
This guide include steps to simulate the network-side state transitions to illustrate the transitions that occur automatically.
To simulate the network-side transitions, use the LEGACY_DISPUTE value in the type field of the request payload.
This allows you to manually transition the dispute through the card network states by simulating the process of submitting the disputes to card network to better understand the process.
See Submit a Dispute.
The following table outlines how Marqeta and network states relate to each other.
| Marqeta State | Network State |
|---|---|
| OPEN | - |
| OPEN_WITH_ACTION_REQUIRED | - |
| READY | - |
| CHARGEBACK_INITIATED | initiated |
| CHARGEBACK_INITIATED | representment |
| CHARGEBACK_INITIATED | prearbitration |
| CHARGEBACK_INITIATED | arbitration |
| CLOSED | case_won |
| CLOSED | case_lost |
| CLOSED | network_rejected |
Create a dispute
To create a dispute, you must open a case, upload supporting documents, and transition it to theREADY state.
For more information on creating a dispute, see Creating a Dispute.
Opening the dispute case
To open a dispute case, send aPOST /cases request with the following fields:
original_transaction_token: The clearing transaction token.dispute_amount: The amount in dispute.dispute_reason: A reason code (for example,NOT_AUTHORIZED_CARD_ABSENTfor fraud, orCARDHOLDER_DISPUTEfor goods not received).
- The request payload for dispute creation differs depending on the network and dispute reason. The following sample request for a Mastercard cleared transaction is an example of a minimal configuration.
- The
cardholder_contact_dateparameter is required forREG_Edisputes, but it is not required for this example with minimal configuration. - The
dispute_reasonenum is different fromreason_codeon a transition which is a network-side identifier.
Sample request body
Sample request
Sample request
Sample response body
Sample response
Sample response
OPEN or OPEN_WITH_ACTION_REQUIRED Marqeta state.
Uploading supporting documents
To upload supporting documents to defend the dispute claim, usePOST /cases/{token}/contents.
You must upload supporting documents while the case is still in OPEN, OPEN_WITH_ACTION_REQUIRED, or READY states.
Once a dispute is submitted to the card network, you can no longer attach documents.
For this example in particular, Mastercard requires supporting documents for all dispute claims.
Sample request body
You can upload supporting document file to the disputes API as a binary in anapplication/json in the Content-Type field, or as part of a multipart/form-data.
Examples for both modes follow below.
Sample binary in body request
Sample binary in body request
Sample multipart form request
Sample multipart form request
Sample response body
Sample response
Sample response
OPEN or OPEN_WITH_ACTION_REQUIRED.
Verifying the document upload
You can verify that your document was uploaded correctly by sending a request to theGET /cases/{token}/contents endpoint.
The response body includes only the list of uploaded documents.
However, if you want to download these files, include download_link=true as a query parameter to receive the link in the response body.
Sample request body
Transitioning a dispute case
After you provide all the required case information and upload supporting documents, transition the case to theREADY state by performing the REVIEW action.
Use POST /cases/{token}/transitions and set the action field value to REVIEW.
Sample request body
Sample request
Sample request
Sample response body
Sample response
Sample response
READY, and it is now eligible for submission to the card network.
Withdrawing a dispute voluntarily
You can withdraw a dispute while it is in theOPEN, OPEN_WITH_ACTION_REQUIRED, or READY state by sending a request to the POST /cases/<case_token>/transitions endpoint.
This moves the case to a CLOSED state.
Sample request body
Submit a dispute
Once the dispute enters theREADY state, you can submit it to the card network for processing.
Submitting the dispute formally initiates the chargeback with the card network.
Submitting a dispute to the card network
After reviewing the dispute case in aREADY state, Marqeta submits it to the card network and the case transitions to the CHARGEBACK_INITIATED network state.
You can simulate submitting a dispute using a POST /cases/<case_token>/transitions request.
The chargeback can be initiated for a provisional credit or no credit flow.
The example below demonstrates a no-credit chargeback flow by sending CHARGEBACK_NO_CREDIT in the action field.
Sample request body
Sample request
Sample request
Sample response body
Sample response
Sample response
CHARGEBACK_INITIATED Marqeta state and the initiated network state.
If the network rejects the submission, the dispute enters the
network.rejected network state and the Marqeta state transitions to CLOSED.
You can review the case and resubmit it with corrected details.reason_code used must match the action being performed.
Test your webhook handlers based on the selection you make from the following options.
If you select the CHARGEBACK_CREDIT action for provisional credit, the following webhook events are sent:
transactions.authorization.clearing.chargebackchargebacktransitions.initiatedtransactions.authorization.clearing.chargeback.provisional.credit.
CHARGEBACK_NO_CREDIT action for no credit, the following webhook events are sent:
transactions.authorization.clearing.chargebackchargebacktransitions.initiated.
There may be a delay between the time an action is taken and when the webhook is sent.
This is true for all webhooks.
Dispute identifiers
Marqeta and the card network identify a dispute using different tokens, as described below:- Case creation: When a case is created, you have the reason code, and your primary identifier is the transaction token. This is the identifier Marqeta uses to identify the dispute.
- Chargeback initiation: When a chargeback is initiated on the network, you receive both the transaction token and the chargeback token. The card network uses the chargeback token to identify the dispute.
Recommended actions
To effectively track and manage chargebacks, Marqeta recommends that you:- Maintain a mapping: Store the relationship between the reason code and the transaction token within your system.
- Link the identifiers: Once a chargeback is initiated, use the chargeback token to tie the network event back to the original transaction token.
- Associate the reason code: Ensure the reason code is associated with the chargeback token for future tracking.
- The chargeback token will be the identifier that is sent throughout the lifecycle of disputes in all subsequent webhooks.
- There can be multiple disputes associated with a transaction. Hence, the chargeback token is the right identifier to map to a reason code.
Providing provisional credit
Granting provisional credit is required if your program is subject to specific regulations. You are responsible for providing this credit if your program manages the ledger via Just-in-Time (JIT) funding. For this example, which uses theCHARGEBACK_NO_CREDIT action, the system does not require provisional credit.
However, this section provides an example of requesting provisional credit below for reference.
Sample request body
Simulating Merchant representment
In some cases, the acquiring bank may forward the dispute claim to the merchant. A merchant may choose to accept the dispute or challenge it. Marqeta might request additional documentation from the cardholder to resubmit the dispute. After the representment is received from the merchant, card network reviews the information to determine if the cardholder or merchant wins the dispute. In the sandbox, you can simulate merchant representment (the merchant’s response to the dispute) using thePOST /cases/<case_token>/disputetransitions endpoint.
Define the amount field within the network_details.representment_details object in the request body to simulate the representment.
Sample request body
Sample request
Sample request
Sample response body
Sample response
Sample response
representment and Marqeta state remains as CHARGEBACK_INITIATED.
If the merchant challenges the chargeback, you receive an authorization.clearing.representment event.
Representment in Visa
When a dispute goes through the Visa network, the representment state does not always apply. Visa uses the following dispute flows depending on the reason code provided:-
Collaboration: For reason codes related to fraud and authorization.
This flow can simplify the case management process and move it along faster.
- Collaboration flow: Initiated → Representment → Prearbitration (decline or responded) → Arbitration.
-
Allocation: For all other reason codes.
The allocation flow skips the representment portion and moves directly into pre-arbitration.
State transitions for each flow is as described:
- Allocation flow: Initiated → Prearbitration (decline or responded) → Arbitration.
Simulating prearbitration
If Marqeta chooses to challenge the merchant’s representment, it moves the dispute to theprearbitration network state, which allows the involved parties to provide further evidence.
You can simulate this transition into prearbitration.
You can simulate the pre-arbitration action by the acquirer by passing RESPOND_WITH_PREARB in the action field.
Sample request body
Sample request
Sample request
Sample response body
Sample response
Sample response
prearbitration and Marqeta state remains as CHARGEBACK_INITIATED.
Marqeta sends you the chargebacktransitions.prearbitration webhook.
Responding to prearbitration
At this point, the merchant can submit further evidence for the case. The specific requirements for theprearbitration_response_details object differ across the various card networks.
You can simulate the reponse to pre-arbitration action to the acquirer by passing RESPOND_WITH_PREARB_RESPONSE in the action field.
This example follows the Mastercard object, which requires only a list of associated document UUIDs in the attached_contents field in the network_details.prearbitration_response_details object.
Sample request body
Sample request
Sample request
Sample response body
Sample response
Sample response
prearbitration and Marqeta state remains as CHARGEBACK_INITIATED.
The chargebacktransitions.prearbitration.responded webhook event sent.
Moving to arbitration
Assume that the acquirer (merchant) does not agree with the pre-arbitration process. You can simulate an arbitration request to proceed by passingRESPOND_WITH_ARB in the action field.
At this point, Marqeta transitions the dispute to the card network, who will provide the final and indisputable decision on the case.
Sample request body
Sample request
Sample request
Sample response body
Sample response
Sample response
arbitration and the Marqeta state remains as CHARGEBACK_INITIATED.
Marqeta sends you the chargebacktransitions.arbitration webhook.
Closing the case and notifying the cardholder
At this stage, the network has decided whether the case is won or lost. In production, you must notify the cardholder of the outcome. To simulate this transition, use one of the following actions:CLOSE_WITH_CASE_WONCLOSE_WITH_NETWORK_REJECTED
case.won flow by sending CLOSE_WITH_CASE_WON in the action field.
Sample request body
Sample request
Sample request
Sample response body
Sample response
Sample response
CLOSED regardless of the decision and the network state transitions to case.won or case.lost automatically, based on this decision.
Confirming the dispute status
Marqeta state for dispute is nowCLOSED.
You can check the state of your Dispute with the following request.
Sample request body
Sample request
Sample request