Disputes
The Dispute API is designed to collect chargeback data from our Payments partners whenever a financial dispute is initiated. With this API, partners can create up to three disputes for a specific store, order, and transaction, including details such as the reason, evidence, and dispute amount. Additionally, the API supports updating the status and evidence of a dispute and retrieving details for a single dispute.
Dispute States
A dispute can have four states: needs_response
, under_review
, won
, and lost
. When a dispute is created, it always starts in the needs_response
state and can then transition to the other states according to the following logic:
Valid Transitions
- needs_response -> under_review -> won: The merchant submits evidence, the dispute is reviewed, and the resolution favors the merchant (state won).
- needs_response -> under_review -> lost: The merchant submits evidence, the dispute is reviewed, and the resolution favors the consumer (state lost).
- needs_response -> won: The merchant wins the dispute directly without going through under_review (this could happen if evidence is not required or is validated without review).
- needs_response -> lost: The merchant loses the dispute directly without going through under_review (this could happen if the dispute is rejected without review).
Invalid Transitions
- under_review -> needs_response: A dispute under review should not revert to the initial state.
- won -> needs_response: A dispute resolved as won should not revert to the initial state.
- lost -> needs_response: A dispute resolved as lost should not revert to the initial state.
- won -> under_review: A dispute resolved as won should not transition back to the review state.
- lost -> under_review: If a dispute has already been resolved as lost, it should not transition back to a review state.
- won -> lost: A dispute resolved as won should not transition to the lost state.
- lost -> won: A dispute resolved as lost should not transition to the won state.
API Endpoints
The Dispute API consists of three endpoints, defined in Nuvemshop's public API as follows:
-
POST /dispute
: Creates a dispute associated with an order and a transaction. -
PUT /dispute
: Updates the details of an existing dispute. -
GET /dispute
: Retrieves information about a dispute related to an order.
The token provided in the headers of the Dispute API endpoints is used to validate that the partner's application has the necessary scope to perform actions on the API. The required scope for these actions is write_payments
. Additionally, the app_id
associated with the token is used to filter disputes created by that application, ensuring that only disputes linked to the corresponding app_id
can be accessed or modified. This mechanism ensures that partners can only interact with disputes for which they have specific permissions.
POST /dispute
This endpoint will create a new Dispute in the needs_response
state.
- URL:
POST https://api.tiendanube.com/v1/:store_id/orders/:order_id/transactions/:transaction_id/disputes
- Payload: See Payload
- Headers:
{"Authorization": "Bearer <access_token>"}
- Response:
- Status: 201
- Body:
{"id": "<id>"}
POST Payload
Field | Type | Required | Description |
---|---|---|---|
reason_code | One of: ReasonCode | True | Code that identifies the reason why the dispute was created. |
external_reason_code | String | True | Code that identifies the reason for the dispute according to the card operator. |
amount | Money | True | Amount of the dispute. |
evidence_url | String | False | HTTPS URL to access dispute details on the payment provider. |
evidence_sent_at | Date (ISO 8601 format) | False | Date when the evidence for the dispute was sent. |
initiated_at | Date (ISO 8601 format) | True | Date when the dispute was registered. |
evidence_due_at | Date (ISO 8601 format) | False | Deadline to submit evidence for the dispute. |
Reason Codes
Value | Type | Description |
---|---|---|
bank_cannot_process | String | The bank was unable to process the transaction, possibly due to a system error or malfunction. |
check_returned | String | A check related to the transaction was returned unpaid by the bank. |
credit_not_processed | String | The credit or refund promised to the cardholder was not processed or received. |
customer_initiated | String | The cardholder initiated the dispute, often due to dissatisfaction or unrecognized transaction. |
debit_not_authorized | String | The debit transaction was not authorized by the cardholder. |
duplicate_transaction | String | The transaction is a duplicate of another transaction that has already been processed. |
fraudulent_activity | String | The transaction is suspected to be fraudulent or unauthorized by the cardholder. |
incorrect_account_details | String | The transaction was processed with incorrect account details, such as an incorrect account number. |
insufficient_funds | String | The cardholder's account had insufficient funds to cover the transaction amount. |
product_not_received | String | The cardholder claims they did not receive the product or service purchased. |
product_unacceptable | String | The cardholder received the product or service but found it to be defective, damaged, or not as described. |
subscription_canceled | String | The cardholder was charged for a subscription or recurring service after they had canceled it. |
unrecognized | String | The cardholder does not recognize the transaction on their statement and believes it may be unauthorized. |
Money
Field | Type | Description |
---|---|---|
value | String | Amount of money as a string. E.g. "49.99" . |
currency | String | ISO 4217 code for the currency, such as ARS, BRL, USD, etc. |
Note: Decimal numbers are represented as string format for better decimal precision handling. It must contain two decimal places and use a point as decimal separator.
Examples
Request Example
E.g.
Endpoint
POST https://api.tiendanube.com/v1/1020559/orders/1612216732/transactions/02aaa5c6-080a-40e9-a61f-90ca2150d6a2/disputes
Headers
{
"Authorization": "Bearer 12b2617c3362d9805cdf89079c4c99f928504eda",
"Content-Type": "application/json"
}
Payload
{
"reason_code": "fraudulent_activity",
"external_reason_code": "fraud",
"amount": {
"value": "11.00",
"currency": "ARS"
},
"initiated_at": "2024-12-02T12:30:15.123Z",
"evidence_url": "https://url.com",
"evidence_sent_at": "2024-12-05T12:30:15.123Z",
"evidence_due_at": "2024-12-10T12:30:15.123Z"
}
Response Example
E.g.
{
"id": "67654a1d7f0000f100f03533"
}
PUT /dispute
This endpoint will update an existing Dispute, allowing it to transition to other states. It is important to note that attributes related to evidence can be updated or specified for the first time (if they were not provided during creation). Additionally, in the case of reaching any terminal state, the end date must be specified.
- URL:
PUT https://api.tiendanube.com/v1/:store_id/orders/:order_id/transactions/:transaction_id/disputes/:dispute_id
- Payload: See Payload
- Headers:
{"Authorization": "Bearer <access_token>"}
- Response:
- Status: 204
PUT Payload
Field | Type | Required | Description |
---|---|---|---|
status | String. One of: needs_response , under_review , won , lost | True | Status of the dispute. |
evidence_url | String | False. Ignored if status == won or status == lost | HTTPS URL to access dispute details on the payment provider. |
evidence_sent_at | Date (ISO 8601 format) | False. Ignored if status == won or status == lost | Date when the evidence for the dispute was sent. |
closed_at | Date (ISO 8601 format) | False. Ignored if status != won or status != lost | Date when the dispute was closed. |
Examples
Request Example
E.g.
Endpoint
PUT https://api.tiendanube.com/v1/1020559/orders/1612216732/transactions/02aaa5c6-080a-40e9-a61f-90ca2150d6a2/disputes/67654a1d7f0000f100f03533
Headers
{
"Authorization": "Bearer 12b2617c3362d9805cdf89079c4c99f928504eda",
"Content-Type": "application/json"
}
Payload
{
"status": "won",
"closed_at": "2024-12-02T12:30:15.123Z"
}
GET /dispute
- URL:
GET https://api.tiendanube.com/v1/:store_id/orders/:order_id/transactions/:transaction_id/disputes
- Headers:
{"Authorization": "Bearer <access_token>"}
- Response:
- Status: 200
- Body: See Response
GET Response
Field | Type | Description |
---|---|---|
id | String | ID of the dispute. |
store_id | String | ID of the store. |
order_id | String | ID of the order. |
transaction_id | String | ID of the transaction related to the dispute. |
reason_code | One of: ReasonCode | Code that identifies the reason why the dispute was created. |
external_reason_code | String | Code that identifies the reason for the dispute according to the card operator. |
amount | Money | Amount of the dispute. |
initiated_at | Date (ISO 8601 format) | Date when the dispute was registered. |
evidence_url | String|Null | URL to access dispute details on the payment provider. |
evidence_sent_at | Date (ISO 8601 format)|Null | Date when the evidence for the dispute was sent. |
closed_at | Date (ISO 8601 format|Null | Date when the dispute was closed. |
status | String. One of: needs_response , under_review , won , lost | Current status of the dispute with its associated data. |
evidence_due_at | Date (ISO 8601 format)|Null | Deadline to submit evidence for the dispute. |
history | Array<StateHistory> | List of previous states of the dispute. |
StateHistory
Field | Type | Description |
---|---|---|
status | String. One of: needs_response , under_review , won , lost | State to which the dispute transitioned. |
transitioned_at | Date (ISO 8601 format) | Date when the dispute transitioned. |
Examples
Request Example
Response Example
E.g.
{
"id": "67654a1d7f0000f100f03533",
"store_id": "1020559",
"app_id": "1234",
"order_id": "1612216732",
"transaction_id": "02aaa5c6-080a-40e9-a61f-90ca2150d6a2",
"reason_code": "fraudulent_activity",
"external_reason_code": "fraud",
"amount": {
"value": "11.00",
"currency": "ARS"
},
"initiated_at": "2024-12-02T12:30:15.123Z",
"evidence_url": "https://url.com",
"evidence_sent_at": "2024-12-05T12:30:15.123Z",
"closed_at": "2024-12-02T12:30:15.123Z",
"status": "won",
"evidence_due_at": "2024-12-10T12:30:15.123Z",
"history": [
{
"status": "needs_response",
"transitioned_at": "2024-12-02T12:30:15.123Z"
},
{
"status": "won",
"transitioned_at": "2024-12-20T10:42:45.086783Z"
}
]
}