Closed frnsys closed 7 years ago
Our fake nonces are effectively one-time-use, but subscription calls need a payment method that they can hit periodically.
Subscription.create()
calls will only accept a nonce if it is directly tied to a payment method in your Vault. You can generate a nonce like this by using PaymentMethodNonce.create()
and passing it a token from your Vault. For example:
nonce_create = braintree.PaymentMethodNonce.create('A_PAYMENT_METHOD_TOKEN')
nonce = nonce_create.payment_method_nonce.nonce
resp = braintree.Subscription.create({
'payment_method_nonce': nonce,
'plan_id': config.BRAINTREE_SUBSCRIPTION_PLAN_ID
})
This shouldn't affect you in production because you'll never use fake nonces.
In production, if you have the payment_method_token
on hand, you do not need to first generate a nonce. You can pass the payment_method_token
directly:
'payment_method_token': 'A_PAYMENT_METHOD_TOKEN',
'plan_id': config.BRAINTREE_SUBSCRIPTION_PLAN_ID
})
If you have a service that takes in a nonce that represents a vaulted payment method from the client (such as a nonce generated with a customer id via the Drop-in UI), you could use the braintree.PaymentMethodNonce.create
to create a nonce that you would pass into that service for server side testing.
@EvanHahn Can you provide an example of what you mean by 'A PAYMENT METHOD TOKEN'?
I'm trying to test the same thing in Ruby (existing Customer, fills out credit card form, establishes subscription)... My server posts the Braintree::Subscription.create() and "works" in reality.
Just trying to get to a way to test it. :-)
@mandysimon88 Evan was explaining that if you must use a nonce in your subscription create call, you can generate a nonce from an existing payment method stored in your vault. The 'A_PAYMENT_METHOD_TOKEN'
bit refers to a token for a payment method already stored in your vault.
In normal use cases though, there'd be no need to generate a nonce first, since you already have the token for the payment method. You can just pass that directly in the create call instead of the nonce. (See https://github.com/braintree/braintree_python/issues/86#issuecomment-294575976)
I found the solution to my problem by using the nonce_for_new_payment_method
available from this spec helper, included with the Braintree gem:
https://github.com/braintree/braintree_ruby/blob/master/spec/integration/braintree/client_api/spec_helper.rb
Recording this here in case anyone else is writing a Ruby controller test involving a Braintree::Subscription.
Here is my working example:
describe 'POST #create (success)' do
let(:organization) { create(:organization) }
let(:valid_card) do
{
number: "4111111111111111",
expiration_month: "11",
expiration_year: "2099"
}
end
let(:nonce) do
organization.update(
braintree_customer_id: Braintree::Customer.create(company: organization.name).customer.id
)
nonce_for_new_payment_method(
credit_card: valid_card,
client_token_options: {customer_id: organization.braintree_customer_id}
)
end
describe 'in Braintree' do
it 'creates a BraintreeSubscription tied to our organization' do
params = { payment_method_nonce: nonce, plan_id: 'monthly-recurring' }
post :create, params: params
.....
// in Controller...
nonce_from_the_client = params[:payment_method_nonce]
result = Braintree::Subscription.create(
payment_method_nonce: nonce_from_the_client,
plan_id: params[:plan_id]
)
result.success? // ...is true
Recommend updating this documentation page, which errantly suggests that the fake valid nonces can be using for recurring billing: https://developers.braintreepayments.com/guides/recurring-billing/testing-go-live/ruby
not sure what I'm doing wrong here, but I'm in a sandbox environment using
nonce='fake-valid-nonce'
here:and keep getting the error "Payment method nonce is invalid."