airwallex 0.3.0 → 0.7.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.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +90 -8
  3. data/README.md +2 -2
  4. data/lib/airwallex/api_operations/delete.rb +3 -3
  5. data/lib/airwallex/api_operations/update.rb +4 -4
  6. data/lib/airwallex/client.rb +15 -11
  7. data/lib/airwallex/configuration.rb +6 -2
  8. data/lib/airwallex/middleware/auth_refresh.rb +21 -7
  9. data/lib/airwallex/resources/account_amendment.rb +29 -0
  10. data/lib/airwallex/resources/beneficiary.rb +96 -0
  11. data/lib/airwallex/resources/billing_customer.rb +48 -0
  12. data/lib/airwallex/resources/billing_price.rb +30 -0
  13. data/lib/airwallex/resources/billing_product.rb +23 -0
  14. data/lib/airwallex/resources/billing_subscription.rb +93 -0
  15. data/lib/airwallex/resources/billing_subscription_item.rb +7 -0
  16. data/lib/airwallex/resources/charge.rb +19 -0
  17. data/lib/airwallex/resources/connected_account.rb +136 -0
  18. data/lib/airwallex/resources/conversion.rb +1 -1
  19. data/lib/airwallex/resources/customer.rb +5 -2
  20. data/lib/airwallex/resources/dispute.rb +48 -28
  21. data/lib/airwallex/resources/funds_split.rb +37 -0
  22. data/lib/airwallex/resources/global_account.rb +137 -0
  23. data/lib/airwallex/resources/global_account_alias.rb +62 -0
  24. data/lib/airwallex/resources/global_account_mandate.rb +26 -0
  25. data/lib/airwallex/resources/global_account_transaction.rb +7 -0
  26. data/lib/airwallex/resources/payment_consent.rb +68 -0
  27. data/lib/airwallex/resources/payment_method.rb +13 -5
  28. data/lib/airwallex/resources/payment_source.rb +52 -0
  29. data/lib/airwallex/resources/quote.rb +5 -3
  30. data/lib/airwallex/resources/rate.rb +2 -7
  31. data/lib/airwallex/version.rb +1 -1
  32. data/lib/airwallex/webhook.rb +6 -2
  33. data/lib/airwallex.rb +15 -0
  34. metadata +18 -3
@@ -6,6 +6,11 @@ module Airwallex
6
6
  # Payment methods allow you to store customer payment credentials securely
7
7
  # and reuse them for future payments without collecting details again.
8
8
  #
9
+ # Note: raw card tokenization via .create requires PCI-scoped "Native API"
10
+ # account access, which isn't enabled by default — if your account isn't
11
+ # provisioned for it, collect cards via Airwallex's hosted checkout or
12
+ # Embedded Elements instead.
13
+ #
9
14
  # @example Create a card payment method
10
15
  # pm = Airwallex::PaymentMethod.create(
11
16
  # type: "card",
@@ -26,24 +31,27 @@ module Airwallex
26
31
  #
27
32
  # @example Update billing details
28
33
  # pm.update(billing: { address: { postal_code: "10001" } })
34
+ #
35
+ # @example Disable a payment method
36
+ # pm.disable
29
37
  class PaymentMethod < APIResource
30
38
  extend APIOperations::Create
31
39
  extend APIOperations::Retrieve
32
40
  extend APIOperations::List
33
- extend APIOperations::Update
34
41
  include APIOperations::Update
35
- extend APIOperations::Delete
36
42
 
37
43
  # @return [String] API resource path for payment methods
38
44
  def self.resource_path
39
45
  "/api/v1/pa/payment_methods"
40
46
  end
41
47
 
42
- # Detach this payment method from its customer
48
+ # Disable this payment method (Airwallex has no delete/detach endpoint;
49
+ # disabling is the real lifecycle operation and preserves history)
43
50
  #
51
+ # @param params [Hash] additional params
44
52
  # @return [PaymentMethod] self
45
- def detach
46
- response = Airwallex.client.post("#{self.class.resource_path}/#{id}/detach", {})
53
+ def disable(params = {})
54
+ response = Airwallex.client.post("#{self.class.resource_path}/#{id}/disable", params)
47
55
  refresh_from(response)
48
56
  self
49
57
  end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Airwallex
4
+ # Represents a Billing Payment Source — the object a BillingSubscription's
5
+ # payment_source_id actually references. NOT the same object as
6
+ # PaymentConsent (/pa/payment_consents).
7
+ #
8
+ # external_id is the id of a PaymentMethod (/pa/payment_methods), not a
9
+ # PaymentConsent's own id. The PaymentConsent is still part of the flow —
10
+ # it's what authorizes that PaymentMethod for merchant-initiated
11
+ # (unscheduled) charges — but the id PaymentSource wants is the underlying
12
+ # PaymentMethod's.
13
+ #
14
+ # @example Full flow: PaymentMethod -> PaymentConsent -> PaymentSource -> BillingSubscription
15
+ # payment_method = Airwallex::PaymentMethod.create(
16
+ # customer_id: customer.id,
17
+ # type: "card",
18
+ # card: { ... } # a real test card in sandbox
19
+ # )
20
+ #
21
+ # consent = Airwallex::PaymentConsent.create(
22
+ # customer_id: customer.id,
23
+ # payment_method: { id: payment_method.id },
24
+ # next_triggered_by: "merchant",
25
+ # merchant_trigger_reason: "unscheduled"
26
+ # )
27
+ # consent.verify(...)
28
+ #
29
+ # source = Airwallex::PaymentSource.create(
30
+ # billing_customer_id: billing_customer.id,
31
+ # external_id: payment_method.id,
32
+ # linked_payment_account_id: connected_account.id
33
+ # )
34
+ #
35
+ # Airwallex::BillingSubscription.create(
36
+ # billing_customer_id: billing_customer.id,
37
+ # legal_entity_id: connected_account.legal_entity_id,
38
+ # collection_method: "AUTO_CHARGE",
39
+ # payment_source_id: source.id,
40
+ # items: [{ price_id: price.id, quantity: 1 }]
41
+ # )
42
+ class PaymentSource < APIResource
43
+ extend APIOperations::Create
44
+ extend APIOperations::Retrieve
45
+ extend APIOperations::List
46
+
47
+ # @return [String] API resource path for billing payment sources
48
+ def self.resource_path
49
+ "/api/v1/billing/payment_sources"
50
+ end
51
+ end
52
+ end
@@ -3,14 +3,16 @@
3
3
  module Airwallex
4
4
  # Quote resource for locked exchange rates
5
5
  #
6
- # Create quotes to lock exchange rates for a short period (typically 30-60 seconds).
7
- # Use quotes to guarantee the rate when executing conversions.
6
+ # Create quotes to lock exchange rates for a period you choose (validity:
7
+ # MIN_1 through HR_24 — see .create). Use quotes to guarantee the rate when
8
+ # executing conversions.
8
9
  #
9
10
  # @example Create a quote
10
11
  # quote = Airwallex::Quote.create(
11
12
  # buy_currency: 'EUR',
12
13
  # sell_currency: 'USD',
13
- # sell_amount: 1000.00
14
+ # sell_amount: 1000.00,
15
+ # validity: "MIN_1"
14
16
  # )
15
17
  # puts "Locked rate: #{quote.client_rate}, expires: #{quote.expires_at}"
16
18
  #
@@ -10,15 +10,10 @@ module Airwallex
10
10
  # rate = Airwallex::Rate.retrieve(buy_currency: 'EUR', sell_currency: 'USD')
11
11
  # puts "1 USD = #{rate.client_rate} EUR"
12
12
  #
13
- # @example Get multiple rates (Note: API may not support multiple at once)
14
- # rate = Airwallex::Rate.retrieve(
15
- # buy_currency: 'EUR',
16
- # sell_currency: 'USD'
17
- # )
18
- #
13
+ # There is no .list /fx/rates/current always returns the rate for one
14
+ # specific currency pair, not a collection.
19
15
  class Rate < APIResource
20
16
  extend APIOperations::Retrieve
21
- extend APIOperations::List
22
17
 
23
18
  def self.resource_path
24
19
  "/api/v1/fx/rates/current"
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Airwallex
4
- VERSION = "0.3.0"
4
+ VERSION = "0.7.0"
5
5
  end
@@ -5,6 +5,8 @@ require "openssl"
5
5
  module Airwallex
6
6
  module Webhook
7
7
  DEFAULT_TOLERANCE = 300 # 5 minutes
8
+ # Timestamps below this are seconds, at/above are milliseconds. Valid until year 2286.
9
+ MS_THRESHOLD = 10_000_000_000
8
10
 
9
11
  module_function
10
12
 
@@ -37,6 +39,8 @@ module Airwallex
37
39
  def verify_timestamp(timestamp, tolerance)
38
40
  current_time = Time.now.to_i
39
41
  timestamp_int = timestamp.to_i
42
+ # Airwallex sends x-timestamp in milliseconds; normalize to seconds before comparing.
43
+ timestamp_int /= 1000 if timestamp_int > MS_THRESHOLD
40
44
 
41
45
  if (current_time - timestamp_int).abs > tolerance
42
46
  raise SignatureVerificationError, "Timestamp outside tolerance (#{tolerance}s)"
@@ -54,11 +58,11 @@ module Airwallex
54
58
  private_class_method :compute_signature, :verify_timestamp, :secure_compare
55
59
 
56
60
  class Event
57
- attr_reader :id, :type, :data, :created_at
61
+ attr_reader :id, :name, :data, :created_at
58
62
 
59
63
  def initialize(attributes = {})
60
64
  @id = attributes["id"]
61
- @type = attributes["type"]
65
+ @name = attributes["name"]
62
66
  @data = attributes["data"]
63
67
  @created_at = attributes["created_at"]
64
68
  end
data/lib/airwallex.rb CHANGED
@@ -26,6 +26,7 @@ require_relative "airwallex/resources/transfer"
26
26
  require_relative "airwallex/resources/beneficiary"
27
27
  require_relative "airwallex/resources/refund"
28
28
  require_relative "airwallex/resources/payment_method"
29
+ require_relative "airwallex/resources/payment_consent"
29
30
  require_relative "airwallex/resources/customer"
30
31
  require_relative "airwallex/resources/batch_transfer"
31
32
  require_relative "airwallex/resources/dispute"
@@ -33,6 +34,20 @@ require_relative "airwallex/resources/rate"
33
34
  require_relative "airwallex/resources/quote"
34
35
  require_relative "airwallex/resources/conversion"
35
36
  require_relative "airwallex/resources/balance"
37
+ require_relative "airwallex/resources/global_account"
38
+ require_relative "airwallex/resources/global_account_transaction"
39
+ require_relative "airwallex/resources/global_account_alias"
40
+ require_relative "airwallex/resources/global_account_mandate"
41
+ require_relative "airwallex/resources/billing_product"
42
+ require_relative "airwallex/resources/billing_price"
43
+ require_relative "airwallex/resources/billing_customer"
44
+ require_relative "airwallex/resources/billing_subscription"
45
+ require_relative "airwallex/resources/billing_subscription_item"
46
+ require_relative "airwallex/resources/payment_source"
47
+ require_relative "airwallex/resources/connected_account"
48
+ require_relative "airwallex/resources/account_amendment"
49
+ require_relative "airwallex/resources/funds_split"
50
+ require_relative "airwallex/resources/charge"
36
51
 
37
52
  module Airwallex
38
53
  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.3.0
4
+ version: 0.7.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: 2025-11-25 00:00:00.000000000 Z
11
+ date: 2026-08-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -80,14 +80,29 @@ files:
80
80
  - lib/airwallex/list_object.rb
81
81
  - lib/airwallex/middleware/auth_refresh.rb
82
82
  - lib/airwallex/middleware/idempotency.rb
83
+ - lib/airwallex/resources/account_amendment.rb
83
84
  - lib/airwallex/resources/balance.rb
84
85
  - lib/airwallex/resources/batch_transfer.rb
85
86
  - lib/airwallex/resources/beneficiary.rb
87
+ - lib/airwallex/resources/billing_customer.rb
88
+ - lib/airwallex/resources/billing_price.rb
89
+ - lib/airwallex/resources/billing_product.rb
90
+ - lib/airwallex/resources/billing_subscription.rb
91
+ - lib/airwallex/resources/billing_subscription_item.rb
92
+ - lib/airwallex/resources/charge.rb
93
+ - lib/airwallex/resources/connected_account.rb
86
94
  - lib/airwallex/resources/conversion.rb
87
95
  - lib/airwallex/resources/customer.rb
88
96
  - lib/airwallex/resources/dispute.rb
97
+ - lib/airwallex/resources/funds_split.rb
98
+ - lib/airwallex/resources/global_account.rb
99
+ - lib/airwallex/resources/global_account_alias.rb
100
+ - lib/airwallex/resources/global_account_mandate.rb
101
+ - lib/airwallex/resources/global_account_transaction.rb
102
+ - lib/airwallex/resources/payment_consent.rb
89
103
  - lib/airwallex/resources/payment_intent.rb
90
104
  - lib/airwallex/resources/payment_method.rb
105
+ - lib/airwallex/resources/payment_source.rb
91
106
  - lib/airwallex/resources/quote.rb
92
107
  - lib/airwallex/resources/rate.rb
93
108
  - lib/airwallex/resources/refund.rb
@@ -122,7 +137,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
122
137
  - !ruby/object:Gem::Version
123
138
  version: '0'
124
139
  requirements: []
125
- rubygems_version: 3.5.11
140
+ rubygems_version: 3.5.16
126
141
  signing_key:
127
142
  specification_version: 4
128
143
  summary: Production-grade Ruby client for the Airwallex API