How to make a braintree subscription with dropin UI and 3DS2? - braintree

I want to create a subscription page using drop-in UI.
Client Side:
I am done with the client-side. I have Drop-in UI implemented and I obtain a payment nonce.
Server Side:
On the server side I receive the nonce from the client but I can't create a subscription with that nonce(I received an unvaulted payment method). I need to create a payment method with this nonce. After this the nonce is consumed, so I need another nonce with 3DS secure (for the subscription creation).
From their documentation I understand that I need to create a second nonce (payment method nonce) and send again to the client for verification. I didn't found any sample of this verification...
The question is how I obtain a second nonce that I need for subscription creation?

Just checked the documentation for 3DS + subscriptions, I can see where there's confusion. You need to switch to Hosted Fields, not Drop-In.
This is because you need to do the following workflow, which Drop-In doesn't support:
Generate a payment method nonce out of a vaulted payment method token (server-side)
Verify that nonce using 3D Secure in your client. Successful results will have a new payment method nonce that is enriched with 3D Secure data. (on the client)
Use the generated 3D Secure enriched nonce in the Subscription.create() call.
3D Secure is a complex workflow, if you have additional questions on implementing this particular workflow, contact Support

The drop-in UI generates a nonce, but this nonce is associated with a vaulted payment method, only if you provide a customer_id when you generate the client_token. In this way you can obtain a bounce that you can use in gateway.subscription.create.
To summary the steps are:
(server) Create a customer without a payment method
(server) Generate a client_token with customer_id from step 1
(client) Generate drop-in UI using client token from step 2
(client) When the end-user adds his payment details drop-in generate a nonce associated with an already vaulted payment method
(server) Call subscription.create with the nonce from step 4
gateway.subscription.create({
"payment_method_nonce": clientNonce,
"plan_id": planId,
"merchant_account_id": merchantAccountId
})

Related

Setting a default payment method using the braintree dropin

I am using Braintree to charge customers for their subscriptions (annually). The customer enters his payment method using the Braintree dropin. The payment method is saved and used to pay for the service on a specific date.
Everything works fine until the customer enters another payment method. My backend uses the default payment method to pay for customers services. The problem is that you cannot change the default payment method using the Braintree dropin (setDefault parameter or similar does not exist, although it would be handy).
It has to be done using the backend SDK, where I can call "update" function on PaymentMethod object, like explained here. But that is not possible, because to update a payment method you need payment method token which is not available when changing the payment method using the dropin. With dropin only PaymentMethodNonce object is available, which according to documentation does not include payment method token. So it's basically impossible to set some payment method as default using the nonce information.
I'm looking for a way to enable the customer to change his default payment method using the Braintree dropin.

Braintree drop in UI generate new nonce

I've integrated the braintree drop in UI in my project and have added paypal, google pay and visa payments. Everything works fine, payments are submitting to the API etc. But if I use submit a payment which fails using the values from - https://developers.braintreepayments.com/reference/general/testing/php#transaction-amounts. The nonce has then been used, amending my basket price and submitting again fails as the nonce has already been used. I've looked through the documentation and all I can find about nonces is that it can only be used once (https://developers.braintreepayments.com/guides/payment-method-nonces) and nothing around refreshing or requesting a new nonce. Ideally I'd like to avoid having to force the user to enter the payment details again.
Is there another way of automatically requesting a new nonce?

Validate whether payment was a success or failure

I am looking to use PayPal to accept a payment through my website. I am looking at the Smart Payment button option. If the payment is successful I need to update something in my website DB. How can I determine whether the payment was successful or not? I cant see anything the API docs.
I also need to retain user context with a PHP session ID. How can I pass that to the paypal site and ensure it is returned with the success / fail indicator?
Use Paypal IPN to receive payment notifications. Setup a server endpoint to respond to IPN requests and update your DB etc...
To maintain state, you will need to include a hidden input filed in your Smart Payment Button with a name of custom and a value of your choice (session id).
Setup a IPN endpoint ie: /checkout/ipn, to receive Paypal notifications. Capture the session ID with $_POST['custom'];
I ended up using the Braintree API for this use case. Ther Brantree API returns a unique payment identifier (payment Nonce) which you can then validate by submitting a call back to the Braintree API to ensure the payment was actually received properly.

Handle Different Cases Using Drop-In UI

I am trying to use the Braintree Drop-In UI with a subscription service on my website. How do I tell my server how to create the subscription?
For Instance:
A user already has a payment method in the vault so when they hit submit my server just uses the payment nonce given to create the subscription since they used a vaulted method.
BUT, what if a user adds a new payment method? How does my server know to create a new payment method for them since it is not vaulted and I cannot just use the nonce to make a new subscription?
Really what I need to know is how can my server know the user is adding a new method versus using one already vaulted in the Drop-In UI.
Full disclosure: I work at Braintree. If you have any further questions, feel free to contact support.
To create a subscription using an existing payment method, first generate a client_token, passing in a customer_id.
#client_token = Braintree::ClientToken.generate(
:customer_id => a_customer_id
)
After passing this client_token into your Drop-in UI, the customer's previous payment methods will be within the form. The customer can then select one of these payment methods, or create a new one, and the new one will be selected.
After form submission, a payment_method_nonce that corresponds to the selected payment_method will be sent to your server. You can then call Subscription.create, passing in the payment_method_nonce. See our payment_method_nonce documentation for more information.
result = Braintree::Subscription.create(
:payment_method_nonce => "payment_method_nonce",
:plan_id => "silver_plan"
)

When to validate paypal IPN when using a queue?

When is it recommended to validate the paypal IPN?
Option 1 - Validate during the handler ipn post, then save and enqueue ipn if valid.
Pros: An attacker can not fill your database by sending fake IPNs
Cons:
Requires a longer response time for ipn post since you need to
make a web request to validate, before being able to respond with a 200 OK in the ipn handler
An attacker can keep your web server busy trying to validate fake IPNs
Option 2 - Delay validation, save and enqueue ipn, respond with 200, then validate when processing the queue.
Pros: Quick response to paypal IPN
Cons: An attacker can fill your database by sending fake IPNs
Or do you do have something additional in place that avoids the problems of these two options?
Edit: I'm using the Paypal Adaptive Payments API, and am wondering what the recommended practice is while using that API.
PayPal now supports sending shared secrets instead of postback validation. I prefer this provided (a) your buttons use HTTPS when posting and (a) your notify_url uses HTTPS.
Postback validation has a number of problems, starting with the requirement that the same POST variables be used in the same order. This isn't implementable e.g. in servlets where you don't have that level of control. However in fact it doesn't appear to actually matter, which casts doubt on other security aspects of the procedure.

Resources