Is it ok to pass payment_method_tokens from client to server? - braintree

I am currently using the braintree server package (Node.js) and am working towards implementing subscriptions.
As an intermediate step, I'm managing a list of payment methods for each customer, which is found inside a customer object: customer.paymentMethods.
I want to be sure that passing this list directly to the client is an ok thing to do. Essentially, I'd like to list all of the current payment methods, and also create a way to add new ones / remove existing ones. When a payment method is selected, I can pass the payment_method_token to the server to perform a particular action with this payment method.
As I'm only passing payment tokens to the user when they have the proper session, it seems safe to be passing tokens around in this way, but I want to be positive that I'm doing this correctly.
Can somebody verify whether or not this approach is ok?

Seems to me that 1) this is a lot of unneeded work and 2) not really what you should be doing...
You should be passing the payment nonce around - the SDKs do all the other work for you - https://developers.braintreepayments.com/start/overview
Specifically, for the subscription flow, see https://developers.braintreepayments.com/guides/recurring-billing/create/node - you need the paymentMethodToken, which comes from the nonce (either from the client or one stored on your server) and a planID that is set up in the Control Panel. The paymentMethodToken is not passed around, it is created (and can/should be stored) server side.

Related

Laravel Cashier - Prevent duplicated Payment Methods

I'm trying to update the payment method of a subscription. I collect the card information using Stripe's js (using a provided setup intent). Then I send the payment method id, provided by Stripe's js, to Laravel to actually update the User's default payment method.
Now, the problem is I want to prevent the User to insert duplicated cards, and the only way to prevent that would be to retrieve all the user current payment methods ($user->paymentMethods();), and check if any of those has the same fingerprint of the one I'm adding as default.
To get the fingerprint of the new payment method I'd need to get the Stripe PaymentMethod object for the id provided by the Stripe's js. The Cashier method to do that would be $user->findPaymentMethod(id).
The problem is that the payment id is not yet added to the User payments methods, so $user->findPaymentMethod($request->payment_method); fails because that payment method does not belong to $user.
The only solution I can think of would be to first add the new payment method, then check for duplicates and remove them ?
It seems like you’ve already found the best approach of adding the method to the user and then looking to see if there are any duplicated fingerprints, even if it is a little inconvenient.
Reviewing the Cashier documentation doesn’t show any obvious way to access the PaymentMethod before it’s attached to the user. It may be worth reaching out to the Laravel devs to see if there is functionality that would make this flow easier to accomplish.

How to avoid synchronous and use asynchronous effectively?

Intro
Hey, my question is kind of hard to explain so I apologize in advance.
Question
I'm trying to implement microservices for our ecommerce and I'm having issues on how to respond to a request when the actual logic and data needs to be determined by other ( 2-3 ) services.
In order to make it easier to understand, I'll give an example.
Lets say User A is trying to buy a product. after clicking on "check out" button these steps should happen.
Flow
Request comes in:
Ecommerce service:
Check if product has enough quantity in inventory.
Publish an event indicating a new order has been created. order:created
Anti Fraud service:
Receives order:created and checks whether the user is a fraud or not
Publishes an event indicating the check was successful. check:succeed
Payment Service:
Receives check:succeed and creates a url to the gateway.
Sends the gateway url to the user. (( this is where the question arises ))
Since all of these steps are asynchronous, how do I respond to the request?
Possible Solution
After the user has requested to checkout, the ecommerce service creates an order and responds immediately with the orderId of newly created order, on client-side the user has to request periodically and check whether the status of order is PENDING PAYMENT, in order to achieve this, the payment service needs to publish payment:created after the order has been approved by the system and then ecommerce service can update the order.
My solution works, but I'm really new to microservices and I want to ask from experts like you on how to implement this in a better way.
I really appreciate if you read this far, Thank you for your time.
your flow is a synchronous process. you need a result from previous step so it has to go step by step.
point of system view:
what matters here is: "how to handle steps?". which reminds me SAGA design pattern (specially when you need a rollback handling) but in general there are two types (choreography and orchestration). The choreography describes the interactions between multiple services, where as orchestration represents control from one party's perspective.
for simplicity you can implement the command pattern or use EAI(Enterprise Application Integration) tools like Apache camel to handle message between endpoints according to the flow.
if you have a lots of visitors it's also better to use a queue between endpoints whether with an orchestrator or without.
point of user view:
when a user click to checkout their cart. they don't expect many of steps or to do more than just wait. as keeping the connection open for response is not a good idea maybe a loader and a periodically ajax call behind it is quite enough while there are other solutions like push notification (then you can consider on fire and forget mechanism).
Your workflow for handling a request as it is defined is totally synchronous. Each step depends on the previous step, and cannot start until it finishes. However, second step does not seem to need data from the first step, so actually they could be executed in parallel.
so, what can be done is start both of them:
Check if product has enough quantity in inventory.
Checks whether the user is a fraud or not
then
wait for response and if both are ok, then creates a url to the gateway. and sends it to the user.
You can create a camel route or any other tool that implements EIP to achieve the functionality

How to verify credit card and post a sale in a single API transaction?

edit:
tl;dr: you can't.
You have to create a payment method in order to verify it. Creating a sale does NOT invoke verification, even if verification is enabled globally.
original:
I'm reading about credit card verification, which apparently isn't done automatically during Braintree_Transaction::sale(), but I don't see any options to enable verification on calling sale().
Do I really have to implement (at least) two separate API transactions just to verify a credit card?
Ideally I would like to use a single call to ::sale() to perform validation, authorization, and capture.
I have already enabled verification through my control panel, and I'm using test credit card number 4000111111111115 which, is supposed to be declined, but i'm getting successful transactions with it.
Do I have to create a payment method separately in order to perform validation, even if I have global validation enabled?
Full disclosure: I work at Braintree. If you have any further questions, feel free to contact support.
To test card verification results, please adjust the amount of your transaction. Because these cards are not linked to real accounts, Braintree cannot make the small authorization charges that are made in production, and instead the API must rely on the amount of the test transaction to dictate the expected response.
In a Production environment, Card verification is triggered by the creation of payment methods, not by transactions. To enable verification, either enable it across all payment methods, or add the verifyCard option to your PaymentMethod::Create call. The response to PaymentMethod::Create in either of these cases will contain a creditCardVerification object if the verification fails for any reason, allowing you to stop the transaction before sale is called.

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"
)

CQRS Task UI - Responding to underlying changes

Been moving into some task oriented UI as a part of my CQRS implementation.
The problem is I have come across the need to update additional properties in my UI as a result of a change made by an initial command sent from the same UI.
My case is different but here's an example...
eg. CommandA Add item to cart resulted in the following events (which all need to be reflected on the UI)
change to store inventory
add item to shopping cart
change total with sales tax
What's the best way to handle this without baking my business logic into my UI?
return a list of resulting events that were performed as a result to the initial command?
return a DTO that reflects changes
other ideas?
I haven't completed it yet, but my idea is to use a Hub from the SignalR framework and subscribe to events and act on them. As long as you can correlate user guids with the connected user guids in SignalR, you can send updates to the correct client and even detect if they still are there.
SignalR isn't that mature yet but the tests I have done works pretty good.
I use it with Knockoutjs and I just update my view models and call functions.
Do those events really need to be reflected in the UI? Consider Amazon, who display "you just added foo to your cart", but don't show any of those other details. That might save you from the problem by redefining it away.
Otherwise, why are you afraid of business logic in the "UI" - specifically, why not include some components from the service that owns each part of that system in your client, and give them the responsibility of doing whatever local updates are appropriate?
In other words, having part of the logic from your sales tax service running in the UI is fine. You (obviously) don't trust it with the billing calculations for tax, but you can totally trust it to do the right thing for the client.
The other advantage of that model is that you get instant feedback for the user, or at least the option of showing instant feedback, without baking more business process knowledge into the client.
For example, recalculating shipping takes time to do - if your client shows a spinner over that, something needs to know to trigger that showing up, right?
If your UI knows that, it has embedded business process around the process. On the other hand, if you have code that is part of the "shipping" service, you can change what response occurs in the client by changing only the one service...

Resources