activemerchant / active_merchant

Active Merchant is a simple payment abstraction library extracted from Shopify. The aim of the project is to feel natural to Ruby users and to abstract as many parts as possible away from the user to offer a consistent interface across all supported gateways.
http://activemerchant.org
MIT License
4.54k stars 2.5k forks source link

CyberSource subscription ID is blank #3502

Open cjmarkham opened 4 years ago

cjmarkham commented 4 years ago

When using a payment token to make a purchase ActiveMerchant gets the subscription ID by splitting the token at a semi colon.

However, the payment token I have which comes from the flex method to tokenize a card doesn't contain a semi colon, which results in a blank string being sent as the subscription ID, failing the transaction.

Here is the code for reference:

gateway = ActiveMerchant::Billing::CyberSourceGateway.new(login: 'x', password: 'x')
gateway.purchase(100, 'THETOKEN')

And the associated StackOverflow post

ActiveMerchant Version: 1.98.0

cjmarkham commented 4 years ago

According to an employee of CyberSource, no token or subscription ID contains a semi colon so I assume 2 pieces of information need to be passed and delimited by a semi colon?

moracca commented 4 years ago

Did you ever figure this out? I have run into similar issues when trying to use a token received via Flex method.

I have tried storing the token with the store method, but passing a string there causes an exception as its expected to be a payment_method not a String, so I get

gateway.store token
NoMethodError: undefined method `first_name' for #<String:0x00000008083c4618>
from vendor/bundle/ruby/2.6/gems/activemerchant-1.114.0/lib/active_merchant/billing/gateways/cyber_source.rb:524:in `block in add_address'

When I try to do authorize or purchase, I am getting the error "One or more fields contains invalid data" and if I look up the transaction in the in the cybersource UI it shows the subscription could not be found (because the subscription id was blank). If I pass ";;;;;;MYTOKEN" as the payment method

(since cyber_source.rb is setting subscription_id = reference.split(';')[6] -- I believe its intending to do this in the case where an attempted charge went into fraud review, where they build a new authorization_from the previous response, which gets formatted as [options[:order_id], response[:requestID], response[:requestToken], action, amount, options[:currency], response[:subscriptionID]].join(';'). In this case the 'reference' is this joined string)

it does correctly fill in my token as the subscription ID if I debug the xml sent in the request, however the transaction still fails with the Reply Message: the subscription (MYTOKEN) could not be found.

I've also tried passing a ActiveMerchant::Billing::NetworkTokenizationCreditCard instance with the token set to the number but that doesn't work properly since the number field can only contain digits.

My understanding was that I could store the flex token and utilize it when making charges. Is there a different process needed to utilize a flex token?

Thanks