airwallex 0.7.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,6 +7,9 @@ module Airwallex
7
7
  extend APIOperations::List
8
8
  include APIOperations::Update
9
9
 
10
+ # Sandbox-only — see https://www.airwallex.com/docs/api/simulation/shopper-actions
11
+ SIMULATION_SHOPPER_ACTION_PATH = "/api/v1/simulation/pa/shopper_actions"
12
+
10
13
  def self.resource_path
11
14
  "/api/v1/pa/payment_intents"
12
15
  end
@@ -40,5 +43,28 @@ module Airwallex
40
43
  refresh_from(response)
41
44
  self
42
45
  end
46
+
47
+ # Simulate the shopper completing a redirect/3DS challenge raised during
48
+ # #confirm, using the `url` from the confirm response's next_action
49
+ #
50
+ # @param url [String] the redirect URL from #confirm's next_action
51
+ # @return [PaymentIntent] self
52
+ def simulate_shopper_pay(url:)
53
+ response = Airwallex.client.post("#{SIMULATION_SHOPPER_ACTION_PATH}/pay", url: url)
54
+ refresh_from(response)
55
+ self
56
+ end
57
+
58
+ # Simulate the shopper abandoning/rejecting a redirect/3DS challenge
59
+ # raised during #confirm, using the `url` from the confirm response's
60
+ # next_action
61
+ #
62
+ # @param url [String] the redirect URL from #confirm's next_action
63
+ # @return [PaymentIntent] self
64
+ def simulate_shopper_reject(url:)
65
+ response = Airwallex.client.post("#{SIMULATION_SHOPPER_ACTION_PATH}/reject", url: url)
66
+ refresh_from(response)
67
+ self
68
+ end
43
69
  end
44
70
  end
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Airwallex
4
+ # Represents an in-person (POS) Terminal used for card-present payments.
5
+ #
6
+ # This gem currently only implements the sandbox Simulation endpoints for
7
+ # driving a terminal through a test payment; it does not yet implement the
8
+ # live terminal create/retrieve/list endpoints.
9
+ # See https://www.airwallex.com/docs/api/simulation/pos-terminals
10
+ #
11
+ # @example Simulate a terminal completing a PaymentIntent
12
+ # Airwallex::POSTerminal.simulate_turn_on(terminal_id: "term_123")
13
+ # Airwallex::POSTerminal.simulate_confirm_payment_intent(
14
+ # terminal_id: "term_123",
15
+ # payment_scenario_name: "approve"
16
+ # )
17
+ class POSTerminal < APIResource
18
+ # @return [String] API resource path for simulated POS terminal actions
19
+ def self.resource_path
20
+ "/api/v1/simulation/pa/pos/terminals"
21
+ end
22
+
23
+ # Simulate turning a terminal on
24
+ #
25
+ # @param terminal_id [String]
26
+ # @return [POSTerminal]
27
+ def self.simulate_turn_on(terminal_id:)
28
+ response = Airwallex.client.post("#{resource_path}/turn_on", terminal_id: terminal_id)
29
+ new(response)
30
+ end
31
+
32
+ # Simulate turning a terminal off
33
+ #
34
+ # @param terminal_id [String]
35
+ # @return [POSTerminal]
36
+ def self.simulate_turn_off(terminal_id:)
37
+ response = Airwallex.client.post("#{resource_path}/turn_off", terminal_id: terminal_id)
38
+ new(response)
39
+ end
40
+
41
+ # Simulate generating a terminal activation code
42
+ #
43
+ # @param request_id [String]
44
+ # @return [Hash] raw response (contains the generated activation code)
45
+ def self.simulate_generate_activation_code(request_id:)
46
+ Airwallex.client.post("#{resource_path}/generate_activation_code", request_id: request_id)
47
+ end
48
+
49
+ # Simulate a terminal confirming a PaymentIntent under a named test
50
+ # scenario (see .simulate_payment_scenarios for valid names)
51
+ #
52
+ # @param terminal_id [String]
53
+ # @param payment_scenario_name [String]
54
+ # @return [POSTerminal]
55
+ def self.simulate_confirm_payment_intent(terminal_id:, payment_scenario_name:)
56
+ response = Airwallex.client.post(
57
+ "#{resource_path}/confirm_payment_intent",
58
+ terminal_id: terminal_id,
59
+ payment_scenario_name: payment_scenario_name
60
+ )
61
+ new(response)
62
+ end
63
+
64
+ # List the test scenario names available to .simulate_confirm_payment_intent
65
+ #
66
+ # @return [Array, Hash] raw response
67
+ def self.simulate_payment_scenarios
68
+ Airwallex.client.get("#{resource_path}/payment_scenarios")
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Airwallex
4
+ # Represents a Request for Information (RFI) — a compliance question
5
+ # Airwallex raises against your account (KYC, an ongoing KYC review, a
6
+ # cardholder, a transaction, payment enablement, or merchant risk).
7
+ #
8
+ # This gem currently only implements the sandbox Simulation endpoints
9
+ # (there is no live create — real RFIs originate from Airwallex's own
10
+ # compliance review, same as Dispute). See
11
+ # https://www.airwallex.com/docs/api/simulation/request-for-information
12
+ #
13
+ # @example Raise a KYC RFI, then close it
14
+ # rfi = Airwallex::RFI.simulate_create(
15
+ # type: "KYC",
16
+ # questions: [{ answer: { type: "TEXT" } }]
17
+ # )
18
+ # rfi.simulate_close
19
+ class RFI < APIResource
20
+ # @return [String] API resource path for simulated RFI actions
21
+ def self.resource_path
22
+ "/api/v1/simulation/rfis"
23
+ end
24
+
25
+ # Simulate Airwallex raising an RFI
26
+ #
27
+ # @param params [Hash] type: (required, one of "KYC", "KYC_ONGOING",
28
+ # "CARDHOLDER", "TRANSACTION", "PAYMENT_ENABLEMENT",
29
+ # "MERCHANT_RISK"); questions: (required, array of
30
+ # { answer: { type: }, sources: [] })
31
+ # @return [RFI]
32
+ def self.simulate_create(params = {})
33
+ response = Airwallex.client.post("#{resource_path}/create", params)
34
+ new(response)
35
+ end
36
+
37
+ # Simulate closing an RFI
38
+ #
39
+ # @param rfi_id [String]
40
+ # @return [RFI]
41
+ def self.simulate_close(rfi_id)
42
+ response = Airwallex.client.post("#{resource_path}/#{rfi_id}/close", {})
43
+ new(response)
44
+ end
45
+
46
+ # Simulate a follow-up on an RFI — reopen an existing answered question
47
+ # (by id) or append a new one
48
+ #
49
+ # @param rfi_id [String]
50
+ # @param params [Hash] questions: (required, array of
51
+ # { id: } or { answer: { type: }, sources: [] })
52
+ # @return [RFI]
53
+ def self.simulate_follow_up(rfi_id, params = {})
54
+ response = Airwallex.client.post("#{resource_path}/#{rfi_id}/follow_up", params)
55
+ new(response)
56
+ end
57
+
58
+ # Simulate closing this RFI
59
+ #
60
+ # @return [RFI] self
61
+ def simulate_close
62
+ response = Airwallex.client.post("#{self.class.resource_path}/#{id}/close", {})
63
+ refresh_from(response)
64
+ self
65
+ end
66
+
67
+ # Simulate a follow-up on this RFI
68
+ #
69
+ # @param params [Hash] questions: (required)
70
+ # @return [RFI] self
71
+ def simulate_follow_up(params = {})
72
+ response = Airwallex.client.post("#{self.class.resource_path}/#{id}/follow_up", params)
73
+ refresh_from(response)
74
+ self
75
+ end
76
+ end
77
+ end
@@ -6,6 +6,9 @@ module Airwallex
6
6
  extend APIOperations::Retrieve
7
7
  extend APIOperations::List
8
8
 
9
+ # Sandbox-only — see https://www.airwallex.com/docs/api/simulation/transfers
10
+ SIMULATION_PATH = "/api/v1/simulation/transfers"
11
+
9
12
  def self.resource_path
10
13
  "/api/v1/transfers"
11
14
  end
@@ -19,5 +22,38 @@ module Airwallex
19
22
  refresh_from(response)
20
23
  self
21
24
  end
25
+
26
+ # Simulate this transfer's status advancing one step. The standard
27
+ # lifecycle is SCHEDULED -> PROCESSING -> SENT -> PAID, progressed one
28
+ # step at a time; OVERDUE, FAILED, and CANCELLED can be jumped to
29
+ # directly.
30
+ #
31
+ # @param next_status [String] one of "OVERDUE", "PROCESSING", "SENT",
32
+ # "PAID", "FAILED", "CANCELLED"
33
+ # @param failure_type [String, nil] failure reason code, only
34
+ # meaningful when next_status is "FAILED"
35
+ # @return [Transfer] self
36
+ def simulate_transition(next_status:, failure_type: nil)
37
+ params = { next_status: next_status }
38
+ params[:failure_type] = failure_type if failure_type
39
+ response = Airwallex.client.post("#{SIMULATION_PATH}/#{id}/transition", params)
40
+ refresh_from(response)
41
+ self
42
+ end
43
+
44
+ # Simulate a transfer's status advancing one step
45
+ #
46
+ # @param transfer_id [String]
47
+ # @param next_status [String] one of "OVERDUE", "PROCESSING", "SENT",
48
+ # "PAID", "FAILED", "CANCELLED"
49
+ # @param failure_type [String, nil] failure reason code, only
50
+ # meaningful when next_status is "FAILED"
51
+ # @return [Transfer]
52
+ def self.simulate_transition(transfer_id, next_status:, failure_type: nil)
53
+ params = { next_status: next_status }
54
+ params[:failure_type] = failure_type if failure_type
55
+ response = Airwallex.client.post("#{SIMULATION_PATH}/#{transfer_id}/transition", params)
56
+ new(response)
57
+ end
22
58
  end
23
59
  end
@@ -40,11 +40,14 @@ module Airwallex
40
40
  hash.transform_keys(&:to_sym)
41
41
  end
42
42
 
43
- def deep_symbolize_keys(hash)
44
- return hash unless hash.is_a?(Hash)
45
-
46
- hash.each_with_object({}) do |(key, value), result|
47
- result[key.to_sym] = value.is_a?(Hash) ? deep_symbolize_keys(value) : value
43
+ def deep_symbolize_keys(value)
44
+ case value
45
+ when Hash
46
+ value.each_with_object({}) { |(k, v), result| result[k.to_sym] = deep_symbolize_keys(v) }
47
+ when Array
48
+ value.map { |v| deep_symbolize_keys(v) }
49
+ else
50
+ value
48
51
  end
49
52
  end
50
53
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Airwallex
4
- VERSION = "0.7.0"
4
+ VERSION = "0.9.0"
5
5
  end
data/lib/airwallex.rb CHANGED
@@ -48,6 +48,13 @@ require_relative "airwallex/resources/connected_account"
48
48
  require_relative "airwallex/resources/account_amendment"
49
49
  require_relative "airwallex/resources/funds_split"
50
50
  require_relative "airwallex/resources/charge"
51
+ require_relative "airwallex/resources/deposit"
52
+ require_relative "airwallex/resources/issuing_transaction"
53
+ require_relative "airwallex/resources/cardholder"
54
+ require_relative "airwallex/resources/linked_account"
55
+ require_relative "airwallex/resources/account_offboarding"
56
+ require_relative "airwallex/resources/rfi"
57
+ require_relative "airwallex/resources/pos_terminal"
51
58
 
52
59
  module Airwallex
53
60
  class << self
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: airwallex
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chayut Orapinpatipat
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-08-28 00:00:00.000000000 Z
11
+ date: 2026-09-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -81,6 +81,7 @@ files:
81
81
  - lib/airwallex/middleware/auth_refresh.rb
82
82
  - lib/airwallex/middleware/idempotency.rb
83
83
  - lib/airwallex/resources/account_amendment.rb
84
+ - lib/airwallex/resources/account_offboarding.rb
84
85
  - lib/airwallex/resources/balance.rb
85
86
  - lib/airwallex/resources/batch_transfer.rb
86
87
  - lib/airwallex/resources/beneficiary.rb
@@ -89,23 +90,29 @@ files:
89
90
  - lib/airwallex/resources/billing_product.rb
90
91
  - lib/airwallex/resources/billing_subscription.rb
91
92
  - lib/airwallex/resources/billing_subscription_item.rb
93
+ - lib/airwallex/resources/cardholder.rb
92
94
  - lib/airwallex/resources/charge.rb
93
95
  - lib/airwallex/resources/connected_account.rb
94
96
  - lib/airwallex/resources/conversion.rb
95
97
  - lib/airwallex/resources/customer.rb
98
+ - lib/airwallex/resources/deposit.rb
96
99
  - lib/airwallex/resources/dispute.rb
97
100
  - lib/airwallex/resources/funds_split.rb
98
101
  - lib/airwallex/resources/global_account.rb
99
102
  - lib/airwallex/resources/global_account_alias.rb
100
103
  - lib/airwallex/resources/global_account_mandate.rb
101
104
  - lib/airwallex/resources/global_account_transaction.rb
105
+ - lib/airwallex/resources/issuing_transaction.rb
106
+ - lib/airwallex/resources/linked_account.rb
102
107
  - lib/airwallex/resources/payment_consent.rb
103
108
  - lib/airwallex/resources/payment_intent.rb
104
109
  - lib/airwallex/resources/payment_method.rb
105
110
  - lib/airwallex/resources/payment_source.rb
111
+ - lib/airwallex/resources/pos_terminal.rb
106
112
  - lib/airwallex/resources/quote.rb
107
113
  - lib/airwallex/resources/rate.rb
108
114
  - lib/airwallex/resources/refund.rb
115
+ - lib/airwallex/resources/rfi.rb
109
116
  - lib/airwallex/resources/transfer.rb
110
117
  - lib/airwallex/util.rb
111
118
  - lib/airwallex/version.rb
@@ -137,7 +144,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
137
144
  - !ruby/object:Gem::Version
138
145
  version: '0'
139
146
  requirements: []
140
- rubygems_version: 3.5.16
147
+ rubygems_version: 3.4.10
141
148
  signing_key:
142
149
  specification_version: 4
143
150
  summary: Production-grade Ruby client for the Airwallex API