Class: Airwallex::Dispute

Inherits:
APIResource show all
Extended by:
APIOperations::List, APIOperations::Retrieve
Includes:
APIOperations::Update
Defined in:
lib/airwallex/resources/dispute.rb

Overview

Dispute resource for handling chargebacks and payment disputes

Disputes represent chargebacks or payment disputes initiated by cardholders. Merchants can view disputes, challenge them with evidence, or accept them. There is no live create — real disputes originate from card networks/issuing banks. In the sandbox, .simulate_create (and #simulate_escalate/#simulate_resolve) stand in for the card network/issuing bank to drive the full dispute lifecycle for testing. See https://www.airwallex.com/docs/api/simulation/payment-disputes

Examples:

List open disputes

disputes = Airwallex::Dispute.list(status: 'OPEN')

Retrieve a dispute

dispute = Airwallex::Dispute.retrieve('dis_123')

Accept a dispute

dispute.accept

Challenge a dispute

dispute.challenge(...)

Simulate the full sandbox lifecycle

dispute = Airwallex::Dispute.simulate_create(
  payment_intent_id: "int_123",
  reason_code: "4853",
  stage: "CHARGEBACK",
  due_at: "2026-12-01T23:59:59Z"
)
dispute.challenge(customer_communication: "Email thread")
dispute.simulate_resolve(in_favor_of: "MERCHANT")

Constant Summary collapse

SIMULATION_PATH =
"/api/v1/simulation/pa/payment_disputes"

Instance Attribute Summary

Attributes inherited from APIResource

#attributes, #id

Class Method Summary collapse

Instance Method Summary collapse

Methods included from APIOperations::Retrieve

retrieve

Methods included from APIOperations::List

list

Methods included from APIOperations::Update

included, #save, #update

Methods inherited from APIResource

#changed_attributes, #dirty?, #initialize, #inspect, #method_missing, #refresh, #refresh_from, resource_name, #respond_to_missing?, symbolized_get, symbolized_post, #to_hash, #to_json, #to_s

Constructor Details

This class inherits a constructor from Airwallex::APIResource

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class Airwallex::APIResource

Class Method Details

.resource_pathObject



43
44
45
# File 'lib/airwallex/resources/dispute.rb', line 43

def self.resource_path
  "/api/v1/pa/payment_disputes"
end

.simulate_create(params = {}) ⇒ Dispute

Simulate a card network/issuing bank raising a dispute against a PaymentIntent

Parameters:

  • params (Hash) (defaults to: {})

    payment_intent_id:, reason_code: (card-brand specific, e.g. Mastercard "4853", Visa "10.4"), stage: (one of "RFI", "PRE_CHARGEBACK", "CHARGEBACK", "PRE_ARBITRATION", "ARBITRATION"), due_at: (required); amount:, comment:, documents: (optional)

Returns:



56
57
58
59
# File 'lib/airwallex/resources/dispute.rb', line 56

def self.simulate_create(params = {})
  response = Airwallex.client.post("#{SIMULATION_PATH}/create", params)
  new(response)
end

.simulate_escalate(dispute_id, params = {}) ⇒ Dispute

Simulate the issuing bank rejecting the merchant's challenge evidence and advancing the dispute to the next stage (e.g. Chargeback -> Pre-arbitration). Not valid while status is REQUIRES_RESPONSE — the merchant must #accept or #challenge first.

Parameters:

  • dispute_id (String)
  • params (Hash) (defaults to: {})

    due_at: (required); amount:, comment:, documents: (optional)

Returns:



70
71
72
73
# File 'lib/airwallex/resources/dispute.rb', line 70

def self.simulate_escalate(dispute_id, params = {})
  response = Airwallex.client.post("#{SIMULATION_PATH}/#{dispute_id}/escalate", params)
  new(response)
end

.simulate_resolve(dispute_id, params = {}) ⇒ Dispute

Simulate the issuing bank's final decision on a dispute. in_favor_of: "MERCHANT" resolves it WON/REVERSED; "CUSTOMER" resolves it LOST. Not valid while status is REQUIRES_RESPONSE — the merchant must #accept or #challenge first.

Parameters:

  • dispute_id (String)
  • params (Hash) (defaults to: {})

    in_favor_of: ("MERCHANT" or "CUSTOMER", required); amount: (optional, defaults to the full disputed amount)

Returns:



84
85
86
87
# File 'lib/airwallex/resources/dispute.rb', line 84

def self.simulate_resolve(dispute_id, params = {})
  response = Airwallex.client.post("#{SIMULATION_PATH}/#{dispute_id}/resolve", params)
  new(response)
end

Instance Method Details

#acceptAirwallex::Dispute

Accept a dispute without challenging it

Returns:



92
93
94
95
96
# File 'lib/airwallex/resources/dispute.rb', line 92

def accept
  response = Airwallex.client.post("#{self.class.resource_path}/#{id}/accept", {})
  refresh_from(response)
  self
end

#challenge(params = {}) ⇒ Airwallex::Dispute

Challenge a dispute with evidence

Parameters:

  • params (Hash) (defaults to: {})

    challenge params — exact shape unconfirmed, pass through whatever Airwallex's challenge schema requires

Returns:



103
104
105
106
107
# File 'lib/airwallex/resources/dispute.rb', line 103

def challenge(params = {})
  response = Airwallex.client.post("#{self.class.resource_path}/#{id}/challenge", params)
  refresh_from(response)
  self
end

List payment intents related to this dispute

Parameters:

  • params (Hash) (defaults to: {})

    additional query params (e.g. pagination)

Returns:



136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/airwallex/resources/dispute.rb', line 136

def related_payment_intents(params = {})
  response = Airwallex.client.get(
    "#{self.class.resource_path}/#{id}/related_payment_intents", params
  )

  ListObject.new(
    data: extract_items(response),
    has_more: extract_has_more(response),
    next_cursor: extract_next_cursor(response),
    resource_class: PaymentIntent,
    params: params
  )
end

#simulate_escalate(params = {}) ⇒ Airwallex::Dispute

Simulate the issuing bank rejecting this dispute's challenge evidence and advancing it to the next stage

Parameters:

  • params (Hash) (defaults to: {})

    due_at: (required); amount:, comment:, documents: (optional)

Returns:



115
116
117
118
119
# File 'lib/airwallex/resources/dispute.rb', line 115

def simulate_escalate(params = {})
  response = Airwallex.client.post("#{self.class::SIMULATION_PATH}/#{id}/escalate", params)
  refresh_from(response)
  self
end

#simulate_resolve(params = {}) ⇒ Airwallex::Dispute

Simulate the issuing bank's final decision on this dispute

Parameters:

  • params (Hash) (defaults to: {})

    in_favor_of: ("MERCHANT" or "CUSTOMER", required); amount: (optional)

Returns:



126
127
128
129
130
# File 'lib/airwallex/resources/dispute.rb', line 126

def simulate_resolve(params = {})
  response = Airwallex.client.post("#{self.class::SIMULATION_PATH}/#{id}/resolve", params)
  refresh_from(response)
  self
end