Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Sync upstream 5 Aug 2024 #20

Closed
wants to merge 47 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
e282efb
Update the error_code_from method to grab and alpha_numeric character…
DustinHaefele Jun 12, 2024
32e4da3
Braintree Blue: add graceul failure if zipcode is not present
yunnydang Jun 4, 2024
23169a5
DLocal: update the zip and ip fields
yunnydang Jun 6, 2024
5bd880f
Litle: Add tests for network tokenization (#5145)
Buitragox Jun 18, 2024
b636002
Datatrans: Add support for verify transactions (#5148)
pipe2442 Jun 21, 2024
d31c20c
Checkout V2: add support for risk data fields
yunnydang Jun 20, 2024
94377a3
Pin: Add new 3DS params mentioned in Pin Payments docs (#4720)
hudakh Jun 24, 2024
80c3cb5
RedsysRest: Add support for stored credentials & 3DS exemptions
jherreraa May 22, 2024
3805b4b
Fix rubocop error
Jun 25, 2024
2aa3c32
Datatrans: Fix InvalidCountryCodeError (#5156)
pipe2442 Jun 27, 2024
819907d
CheckoutV2: truncate the reference id for amex transactions
yunnydang Jun 24, 2024
17b9ff8
Worldpay: Support AFTs (#5154)
curiousepic Jun 28, 2024
a26afd1
CommerceHub: Add billing address name overide
yunnydang Jun 27, 2024
d6b4500
Stripe PI: add optional ability for 3DS exemption on verify calls
yunnydang Jul 1, 2024
c5a4d22
CyberSource: Update Stored Credential flow
May 29, 2024
3274d5b
Orbital: Update to accept UCAF Indicator GSF
Jun 24, 2024
b72e61f
FlexCharge: Adding authorize-capture functionality
Heavyblade Jul 2, 2024
00b2ae7
CyberSource: Add the merchant_descriptor_city and submerchant_id fields
yunnydang Jul 1, 2024
83bb31d
FlexCharge: Enabling void call
Heavyblade Jul 9, 2024
b3e12ee
CyberSource: bugfix - send correct card type/code for carnet
rachelkirk Jul 9, 2024
6f024c9
MerchantWarrior: Update phone, email, ip and store_ID
Jun 28, 2024
4f34933
Credorax: Update 3DS version mapping
Jul 1, 2024
0ae0158
FlexCharge - NoMethodError: nil CreditCard#number (#5164)
pipe2442 Jul 11, 2024
8dc76a4
FlexCharge: quick fix on void call
Heavyblade Jul 10, 2024
19d3979
Fix bug where `add_payment_method` was incorrectly returned early if …
naashton Jul 12, 2024
f270a60
Add neew Bins: Maestro
yunnydang Jul 11, 2024
dfaccf4
Braintree: Remove stored credential v1
Jul 12, 2024
957dd75
Plexo: Update Network Token implementation (#5169)
javierpedrozaing Jul 16, 2024
941c6d2
NMI: Adding GooglePay and ApplePay (#5146)
javierpedrozaing Jul 17, 2024
568466b
Braintree: Pass overridden mid into client token for GS 3DS (#5166)
sinourain Jul 17, 2024
27ae6b7
Moneris: Update crypt_type for 3DS
Jul 2, 2024
4b4ccb9
Update CheckoutV2 3DS message & error code
Jul 12, 2024
214d483
SER-1386 add ExtraData and Source GSFs
Heavyblade Jul 15, 2024
a2b79f4
SER-1387 fix shipping address and idempotency key
Heavyblade Jul 19, 2024
39878f6
Datatrans: Add TPV
Jul 17, 2024
cc7ec9b
FlexCharge: change transactionType placement
Heavyblade Jul 23, 2024
3f85ecd
Rapyd: Add support for save_payment_method field
rachelkirk Jul 24, 2024
efd27e7
Datatrans: Modify authorization_from string for store (#5193)
gasb150 Jul 26, 2024
d0f7615
DecidirPlus: Update error_message to add safety navigator
Jul 18, 2024
d4b63b4
Elavon: Update Stored Credentials
Jul 10, 2024
e9ea86f
Elavon: Update cvv for stored credential
Aug 1, 2024
0c9acc1
Adyen: Include header fields in response body
yunnydang Jul 17, 2024
d9cffb6
Stripe and Stripe PI: add headers to response body
yunnydang Jul 17, 2024
f788fd8
Fatzebra: fix directory_server_transaction_id mapping (#5197)
gasb150 Aug 1, 2024
f2ed5b6
Upgrade rexml to 3.3.4 to address CVE-2024-39908, 41123, 41946 (#5181)
raymzag Aug 2, 2024
f52d344
Release 1.137.0
byroot Aug 2, 2024
004615d
Merge branch 'master' of https://github.com/activemerchant/active_mer…
raymzag Aug 4, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,38 @@
= ActiveMerchant CHANGELOG

== HEAD

= Version 1.137.0 (August 2, 2024)

* Unlock dependency on `rexml` to allow fixing a CVE (#5181).
* Bump Ruby version to 3.1 [dustinhaefele] #5104
* FlexCharge: Update inquire method to use the new orders end-point
* Worldpay: Prefer options for network_transaction_id [aenand] #5129
* Braintree: Prefer options for network_transaction_id [aenand] #5129
* Cybersource Rest: Update support for stored credentials [aenand] #5083
* Plexo: Add support to NetworkToken payments [euribe09] #5130
* Braintree: Update card verfification payload if billing address fields are not present [yunnydang] #5142
* DLocal: Update the phone and ip fields [yunnydang] #5143
* CheckoutV2: Add support for risk data fields [yunnydang] #5147
* Pin Payments: Add new 3DS params mentioned in Pin Payments docs [hudakh] #4720
* RedsysRest: Add support for stored credentials & 3DS exemptions [jherreraa] #5132
* CheckoutV2: Truncate the reference id for amex transactions [yunnydang] #5151
* CommerceHub: Add billing address name override [yunnydang] #5157
* StripePI: Add optional ability for 3DS exemption on verify calls [yunnydang] #5160
* CyberSource: Update stored credentials [sinourain] #5136
* Orbital: Update to accept UCAF Indicator GSF [almalee24] #5150
* CyberSource: Add addtional invoiceHeader fields [yunnydang] #5161
* MerchantWarrior: Update phone, email, ip and store ID [almalee24] #5158
* Credorax: Update 3DS version mapping [almalee24] #5159
* Add Maestro card bins [yunnydang] #5172
* Braintree: Remove stored credential v1 [almalee24] #5175
* Braintree Blue: Pass overridden mid into client token for GS 3DS [sinourain] #5166
* Moneris: Update crypt_type for 3DS [almalee24] #5162
* CheckoutV2: Update 3DS message & error code [almalee24] #5177
* DecicirPlus: Update error_message to add safety navigator [almalee24] #5187
* Elavon: Add updated stored credential version [almalee24] #5170
* Adyen: Add header fields to response body [yunnydang] #5184
* Stripe and Stripe PI: Add header fields to response body [yunnydang] #5185

== Version 1.136.0 (June 3, 2024)
* Shift4V2: Add new gateway based on SecurionPay adapter [heavyblade] #4860
Expand Down
2 changes: 1 addition & 1 deletion activemerchant.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Gem::Specification.new do |s|
s.add_dependency('builder', '>= 2.1.2', '< 4.0.0')
s.add_dependency('i18n', '>= 0.6.9')
s.add_dependency('nokogiri', '~> 1.4')
s.add_dependency('rexml', '~> 3.2.5')
s.add_dependency('rexml', '~> 3.3', '>= 3.3.4')

s.add_development_dependency('mocha', '~> 1')
s.add_development_dependency('pry')
Expand Down
3 changes: 2 additions & 1 deletion lib/active_merchant/billing/credit_card_methods.rb
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ module CreditCardMethods
501879 502113 502120 502121 502301
503175 503337 503645 503670
504310 504338 504363 504533 504587 504620 504639 504656 504738 504781 504910
505616
507001 507002 507004 507082 507090
560014 560565 561033
572402 572610 572626
Expand Down Expand Up @@ -175,7 +176,7 @@ module CreditCardMethods
(501104..501105),
(501107..501108),
(501104..501105),
(501107..501108),
(501107..501109),
(501800..501899),
(502000..502099),
(503800..503899),
Expand Down
31 changes: 29 additions & 2 deletions lib/active_merchant/billing/gateways/adyen.rb
Original file line number Diff line number Diff line change
Expand Up @@ -755,10 +755,34 @@ def add_metadata(post, options = {})
post[:metadata].merge!(options[:metadata]) if options[:metadata]
end

def add_header_fields(response)
return unless @response_headers.present?

headers = {}
headers['response_headers'] = {}
headers['response_headers']['transient_error'] = @response_headers['transient-error'] if @response_headers['transient-error']

response.merge!(headers)
end

def parse(body)
return {} if body.blank?

JSON.parse(body)
response = JSON.parse(body)
add_header_fields(response)
response
end

# Override the regular handle response so we can access the headers
# set header fields and values so we can add them to the response body
def handle_response(response)
@response_headers = response.each_header.to_h if response.respond_to?(:header)
case response.code.to_i
when 200...300
response.body
else
raise ResponseError.new(response)
end
end

def commit(action, parameters, options)
Expand Down Expand Up @@ -903,7 +927,10 @@ def post_data(action, parameters = {})
end

def error_code_from(response)
response.dig('additionalData', 'refusalReasonRaw').try(:scan, /^\d+/).try(:first) || STANDARD_ERROR_CODE_MAPPING[response['errorCode']] || response['errorCode'] || response['refusalReason']
response.dig('additionalData', 'refusalReasonRaw').try(:match, /^([a-zA-Z0-9 ]{1,5})(?=:)/).try(:[], 1).try(:strip) ||
STANDARD_ERROR_CODE_MAPPING[response['errorCode']] ||
response['errorCode'] ||
response['refusalReason']
end

def network_transaction_id_from(response)
Expand Down
10 changes: 5 additions & 5 deletions lib/active_merchant/billing/gateways/braintree/token_nonce.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ def url
"https://payments#{'.sandbox' if sandbox}.braintree-api.com/graphql"
end

def create_token_nonce_for_payment_method(payment_method)
def create_token_nonce_for_payment_method(payment_method, options = {})
headers = {
'Accept' => 'application/json',
'Authorization' => "Bearer #{client_token}",
'Authorization' => "Bearer #{client_token(options)['authorizationFingerprint']}",
'Content-Type' => 'application/json',
'Braintree-Version' => '2018-05-10'
}
Expand All @@ -34,9 +34,9 @@ def create_token_nonce_for_payment_method(payment_method)
return token, message
end

def client_token
base64_token = @braintree_gateway.client_token.generate
JSON.parse(Base64.decode64(base64_token))['authorizationFingerprint']
def client_token(options = {})
base64_token = @braintree_gateway.client_token.generate({ merchant_account_id: options[:merchant_account_id] || @options[:merchant_account_id] }.compact)
JSON.parse(Base64.decode64(base64_token))
end

private
Expand Down
41 changes: 12 additions & 29 deletions lib/active_merchant/billing/gateways/braintree_blue.rb
Original file line number Diff line number Diff line change
Expand Up @@ -144,16 +144,21 @@ def verify(creditcard, options = {})
exp_month = creditcard.month.to_s
exp_year = creditcard.year.to_s
expiration = "#{exp_month}/#{exp_year}"
zip = options[:billing_address].try(:[], :zip)
address1 = options[:billing_address].try(:[], :address1)
payload = {
credit_card: {
number: creditcard.number,
expiration_date: expiration,
cvv: creditcard.verification_value,
billing_address: {
postal_code: options[:billing_address][:zip]
}
cvv: creditcard.verification_value
}
}
if zip || address1
payload[:credit_card][:billing_address] = {}
payload[:credit_card][:billing_address][:postal_code] = zip if zip
payload[:credit_card][:billing_address][:street_address] = address1 if address1
end

if merchant_account_id = (options[:merchant_account_id] || @merchant_account_id)
payload[:options] = { merchant_account_id: merchant_account_id }
end
Expand Down Expand Up @@ -907,18 +912,10 @@ def add_stored_credential_data(parameters, credit_card_or_vault_id, options)
return unless (stored_credential = options[:stored_credential])

add_external_vault(parameters, options)

if options[:stored_credentials_v2]
stored_credentials_v2(parameters, stored_credential)
else
stored_credentials_v1(parameters, stored_credential)
end
stored_credentials(parameters, stored_credential)
end

def stored_credentials_v2(parameters, stored_credential)
# Differences between v1 and v2 are
# initial_transaction + recurring/installment should be labeled {{reason_type}}_first
# unscheduled in AM should map to '' at BT because unscheduled here means not on a fixed timeline or fixed amount
def stored_credentials(parameters, stored_credential)
case stored_credential[:reason_type]
when 'recurring', 'installment'
if stored_credential[:initial_transaction]
Expand All @@ -935,20 +932,6 @@ def stored_credentials_v2(parameters, stored_credential)
end
end

def stored_credentials_v1(parameters, stored_credential)
if stored_credential[:initiator] == 'merchant'
if stored_credential[:reason_type] == 'installment'
parameters[:transaction_source] = 'recurring'
else
parameters[:transaction_source] = stored_credential[:reason_type]
end
elsif %w(recurring_first moto).include?(stored_credential[:reason_type])
parameters[:transaction_source] = stored_credential[:reason_type]
else
parameters[:transaction_source] = ''
end
end

def add_external_vault(parameters, options = {})
stored_credential = options[:stored_credential]
parameters[:external_vault] = {}
Expand Down Expand Up @@ -1053,7 +1036,7 @@ def bank_account_errors(payment_method, options)
end

def add_bank_account_to_customer(payment_method, options)
bank_account_nonce, error_message = TokenNonce.new(@braintree_gateway, options).create_token_nonce_for_payment_method payment_method
bank_account_nonce, error_message = TokenNonce.new(@braintree_gateway, options).create_token_nonce_for_payment_method(payment_method, options)
return Response.new(false, error_message) unless bank_account_nonce.present?

result = @braintree_gateway.payment_method.create(
Expand Down
34 changes: 23 additions & 11 deletions lib/active_merchant/billing/gateways/checkout_v2.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ def authorize(amount, payment_method, options = {})
post = {}
post[:capture] = false
build_auth_or_purchase(post, amount, payment_method, options)

options[:incremental_authorization] ? commit(:incremental_authorize, post, options, options[:incremental_authorization]) : commit(:authorize, post, options)
end

Expand Down Expand Up @@ -146,6 +147,8 @@ def build_auth_or_purchase(post, amount, payment_method, options)
add_recipient_data(post, options)
add_processing_data(post, options)
add_payment_sender_data(post, options)
add_risk_data(post, options)
truncate_amex_reference_id(post, options, payment_method)
end

def add_invoice(post, money, options)
Expand All @@ -161,6 +164,10 @@ def add_invoice(post, money, options)
post[:metadata][:udf5] = application_id || 'ActiveMerchant'
end

def truncate_amex_reference_id(post, options, payment_method)
post[:reference] = truncate(options[:order_id], 30) if payment_method.respond_to?(:brand) && payment_method.brand == 'american_express'
end

def add_recipient_data(post, options)
return unless options[:recipient].is_a?(Hash)

Expand Down Expand Up @@ -193,6 +200,20 @@ def add_processing_data(post, options)
post[:processing] = options[:processing]
end

def add_risk_data(post, options)
return unless options[:risk].is_a?(Hash)

risk = options[:risk]
post[:risk] = {} unless risk.empty?

if risk[:enabled].to_s == 'true'
post[:risk][:enabled] = true
post[:risk][:device_session_id] = risk[:device_session_id] if risk[:device_session_id]
elsif risk[:enabled].to_s == 'false'
post[:risk][:enabled] = false
end
end

def add_payment_sender_data(post, options)
return unless options[:sender].is_a?(Hash)

Expand Down Expand Up @@ -659,12 +680,7 @@ def message_from(succeeded, response, options)
elsif response['error_type']
response['error_type'] + ': ' + response['error_codes'].first
else
response_summary = if options[:threeds_response_message]
response['response_summary'] || response.dig('actions', 0, 'response_summary')
else
response['response_summary']
end

response_summary = response['response_summary'] || response.dig('actions', 0, 'response_summary')
response_summary || response['response_code'] || response['status'] || response['message'] || 'Unable to read error message'
end
end
Expand Down Expand Up @@ -694,11 +710,7 @@ def error_code_from(succeeded, response, options)
elsif response['error_type']
response['error_type']
else
response_code = if options[:threeds_response_message]
response['response_code'] || response.dig('actions', 0, 'response_code')
else
response['response_code']
end
response_code = response['response_code'] || response.dig('actions', 0, 'response_code')

STANDARD_ERROR_CODE_MAPPING[response_code]
end
Expand Down
22 changes: 18 additions & 4 deletions lib/active_merchant/billing/gateways/commerce_hub.rb
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ def scrub(transcript)
transcript.
gsub(%r((Authorization: )[a-zA-Z0-9+./=]+), '\1[FILTERED]').
gsub(%r((Api-Key: )\w+), '\1[FILTERED]').
gsub(%r(("apiKey\\?":\\?")\w+), '\1[FILTERED]').
gsub(%r(("cardData\\?":\\?")\d+), '\1[FILTERED]').
gsub(%r(("securityCode\\?":\\?")\d+), '\1[FILTERED]').
gsub(%r(("cavv\\?":\\?")\w+), '\1[FILTERED]')
Expand Down Expand Up @@ -171,10 +172,7 @@ def add_billing_address(post, payment, options)
return unless billing = options[:billing_address]

billing_address = {}
if payment.is_a?(CreditCard)
billing_address[:firstName] = payment.first_name if payment.first_name
billing_address[:lastName] = payment.last_name if payment.last_name
end
name_from_address(billing_address, billing) || name_from_payment(billing_address, payment)
address = {}
address[:street] = billing[:address1] if billing[:address1]
address[:houseNumberOrName] = billing[:address2] if billing[:address2]
Expand All @@ -192,6 +190,22 @@ def add_billing_address(post, payment, options)
post[:billingAddress] = billing_address
end

def name_from_payment(billing_address, payment)
return unless payment.respond_to?(:first_name) && payment.respond_to?(:last_name)

billing_address[:firstName] = payment.first_name if payment.first_name
billing_address[:lastName] = payment.last_name if payment.last_name
end

def name_from_address(billing_address, billing)
return unless address = billing

first_name, last_name = split_names(address[:name]) if address[:name]

billing_address[:firstName] = first_name if first_name
billing_address[:lastName] = last_name if last_name
end

def add_shipping_address(post, options)
return unless shipping = options[:shipping_address]

Expand Down
2 changes: 1 addition & 1 deletion lib/active_merchant/billing/gateways/credorax.rb
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ def add_normalized_3d_secure_2_data(post, options)
three_d_secure_options[:eci],
three_d_secure_options[:cavv]
)
post[:'3ds_version'] = three_d_secure_options[:version]&.start_with?('2') ? '2.0' : three_d_secure_options[:version]
post[:'3ds_version'] = three_d_secure_options[:version] == '2' ? '2.0' : three_d_secure_options[:version]
post[:'3ds_dstrxid'] = three_d_secure_options[:ds_transaction_id]
end

Expand Down
Loading
Loading