Braintree API: How can I tell which payment_method is associated with my nonce? - payment

Background:
I create a braintree customer with firstName, lastName and email
I use the dropin ui in checkout form and it creates a payment_method and token and sends me a nonce. Good so far.
I need to add a billing address to the payment_method before I charge the nonce...
Question:
How can I discover which payment_method is associated with my nonce?
Edit to add:
There is a paradoxical reference at the bottom of the javascript+PHP page to an otherwise undocumented [paymentMethodNonce] parameter which uses an also undocumented [options][verifyCard] parameter. I suppose I could run [paymentMethodNonce] sans [options] against each payment_method token associated the user and inspect the errors... lol.

I work at Braintree. If you have more questions, I suggest you reach out to our support team.
When you use the Drop-In UI, it doesn't automatically create a payment method, just a nonce. You pass the nonce back to your server and create a payment method with it:
$result = Braintree_PaymentMethod::create(array(
'customerId' => '12345',
'paymentMethodNonce' => 'nonce-from-the-client'
));
If the nonce points to an already-vaulted payment method for that customer, you'll get back the existing payment method rather than a duplicate.
You can then update that payment method to add a billing address before using it to create a transaction.

Related

Passing Metadata While Generating Stripe Payment Link

I want to pass a few app specific credentials with stripe url for checkout.
I tried something like the following,
const paymentLink = await stripe.paymentLinks.create({
line_items: [{price: "price_1XXXXK", quantity: 1}],
metadata: {
author_id: "author_id",
server_id: "server_id",
},
});
But in payments tab, the metadata is still empty.
I can only see those metadata in generated payment link section. But I can't find any relations or references about the link that was used to make the purchase on the payment response data.
So is there any better way to add metadata to the checkout while creating a payment link, instead of adding metadata just for the generated link?
Passing the metadata parameter when creating a Payment Link will only persist on the generated Checkout Session object, and not the underlying payment:
Metadata associated with this Payment Link will automatically be copied to checkout sessions created by this payment link.
But I can't find any relations or references about the link that was used to make the purchase on the payment response data.
To reconcile the Payment Intent object with the associated Payment Link that was the origin of the payment:
List all Checkout Sessions, passing the payment_intent parameter.
Expand the payment_link field on the returned Checkout Session object.
The Create method for Checkout Sessions supports these parameters:
payment_intent_data
metadata passed this way will be available in both payment_intent.succeeded and charge.succeeded events.
setup_intent_data
subscription_data
That let you pass data to the underlying payment_intent/setup_intent/subscription objects and it supports metadata.
So you'd be able to pass metadata to, say, a PaymentIntent this way.
See: https://support.stripe.com/questions/using-metadata-with-checkout-sessions
In passing / rant: most people will need to use metadata so as to get an "easy" way to know which products are in the order, because out of the box the Stripe API does NOT tell you, in an event, which product was ordered 🙄 (except for Payment Links).

payment intent is null in a subscription checkout session

I am integrating stripe using php by following this tutorial:
https://phppot.com/php/manage-recurring-payments-using-stripe-billing-in-php/
(my website has some subscription plans and redirects to the stripe checkout form ) . however, for the last step, I decided not to use webhooks, I chose to store the info like in this tutorial https://www.codexworld.com/stripe-checkout-payment-gateway-integration-php/ (I know it is not for subscription but I just use the success.php code from this tutorial to collect the customer info and payment intent details).
I tested it, gone throught the stripe checkout form , and on success I printed the checkout session object and noticed that the payment_intent field of that object is empty ! so i cannot load the payment intent object and get its info although the payment is successfully made and it is showing on the dashboard . any idea why ??
EDIT :
According to the documenttaion of a checkout session (https://stripe.com/docs/api/checkout/sessions/object), the payment_intent field stores the ID of the PaymentIntent for Checkout Sessions in payment mode. In my case I have a subscription mode not a payment one. however,if I still want to get the $intent->status , can I use the payment_status field of the session object $checkout_session->payment_status?
And if subcription payments really don't have paymentintents , then why did the payment appear in the payments section on the dashboard?
Based on the mode you passed in, either one of payment_intent, subscription or setup_intent will be populated, the rest will be null.
When a Subscription is made, your user is invoiced so it is considered a payment and will appear in the Payments dashboard. You can retrieve the Subscription and access the latest_invoice field to obtain the Invoice object. The Invoice object contains the payment_intent field. This is likely what you're looking for.
Using webhook would simplify the process, since you could listen to invoice.payment_suceeded to retrieve the PaymentIntent ID.

Stripe - Create subscriptions with a customer with PaymentMethod instead of Source (Token)

I'm integrating Stripe Subscriptions in our workflow, but when creating a subscription with a Customer created with a paymentMethod instead of source I receive the error This customer has no attached payment source.
If I call in the browser createToken() and attach it to the customer in the source field it works.
We integrated one-time payments using the new docs with SCA that use createPaymentMethod() and not createToken(), so our customers are saved with paymentMethod, not source, like explained here:
https://stripe.com/docs/payments/cards/saving-cards-after-payment#save-payment-method
curl https://api.stripe.com/v1/customers \
-u sk_test_secret_token \
-d payment_method="{{PAYMENT_METHOD_ID}}"
Furthermore, in the migration guide it says to replace createToken() with createPaymentMethod().
In Scenario 2: Charging customers off-session for their initial payment, I saw the following:
To create subscriptions and charge customers off-session for their
initial payment, you need to:
1) Use CreatePaymentMethod to collect payment information
2) Create a customer using the ID of the PaymentMethod you created
3) Create the subscription
4) Set up error handling using handleCardSetup for authentication failures and handleCardPayment for authorization failures
I followed those steps. I don't create a SetupIntent (just like I don't create it in one-time payments and it works in these cases), and receive the error I said before when trying to create subscriptions.
Is it possible to create subscriptions with a customer with paymentMethod instead of source?
(We reuse cards using the customers created with paymentMethod for one-time payments, so it would be very important to be able to reuse the same customer/card for subscriptions, without the need for the user input data in stripe elements or anything of the sort, because it would break our flow for reusing cards)
I was able to solve it by including the payment method in the field default_payment_method.
This field is described as follows:
ID of the default payment method for the subscription. It must belong
to the customer associated with the subscription. If not set, invoices
will use the default payment method in the customer’s invoice
settings.
So I assumed that it would use the payment method I associated with the customer when not defined. It seems it is not happening, tough, so I needed to pass it explicitly (is it a Stripe bug? or creating the customer with paymentMethod doesn't make it the default payment method in the customer’s invoice settings? I will contact Stripe to make sure).
Update (2019-09-23)
I contacted Stripe asking if this was a bug and they replied:
[...] With that being said though, this wouldn't be a bug on our end, rather
expected behavior.
If you're wanting for the Payment Method that you're adding to the
customer object to be used on subscriptions, or invoices, by default
without specifying the default_payment_method when creating the
subscription then you would want to attach the Payment Method and
specify the invoice_settings.default_payment_method parameter when
updating the customer. This information can be found within our API
reference here:
https://stripe.com/docs/api/payment_methods/attach
The parameter to use when updating this can be found on the customer
object itself, here:
https://stripe.com/docs/api/customers/update#update_customer-invoice_settings-default_payment_method
This can also be specified upon customer creation, which can be seen
here:
https://stripe.com/docs/api/customers/create#create_customer-invoice_settings-default_payment_method
Specifying this parameter would indicate that the card being added
would be the default for subscriptions, as well as invoices, so that
the default_payment_method wouldn't need to be specified upon the
subscription, or invoice, creation.

BrainTreePayments create new payment method

I am going through the BrainTreePayments documentation page and I came across the Payment Methods. The documentation says "To create a new payment method for an existing customer, the only required attributes are the customer ID and payment method nonce."
gateway.paymentMethod.create({
customerId: "12345",
paymentMethodNonce: nonceFromTheClient
}, function (err, result) { });
The question is
1) How do we create a new payment method for a new customer without payment method nonce?
2) How do we verify the validity of an existing payment method?
Full disclosure: I work at Braintree. If you have any further questions, feel free to contact support.
1) A payment method is like a container to store payment information in your Vault, whereas the payment method nonce is a way to deliver payment information to Braintree. You use a payment method nonce to deliver payment information to create payment methods, transactions, etc. A payment method can be referenced to generate a payment method nonce from stored payment information, but the payment method must store something. You can't create an empty payment method.
2) To verify an existing payment method, use 'PaymentMethod.update()' and include 'verify_card' in your options. If you have enabled fraud tools in your control panel, newly created payment methods for credit cards will be verified before they are stored in the Vault. Cards that are not valid will not be stored and you will receive an error response.

Stripe API: create customer and charge in one request

Lets say I have a new customer who is checking out and wants to store their card for future use. If I'm reading the docs right, I need to make separate calls out to Stripe, one to create the customer with the card and another to charge the card.
Considering the endpoint for creating a charge accepts either a token or a dictionary for the card, I'm suprised the same isn't true for the customer parameter.
I have tried sending a dictionary for the customer in a create charge request to no avail.
Am I forced to make two calls? And if so does Stripe accept feature requests?
Q: Am I forced to make two calls?
A: Yes, you're forced to make two calls to the Stripe API upon creation of a Stripe customer.
If a customer already exists in your database, you only need to make one call to the Stripe API, as shown below. Here, we're creating a charge and passing the retrieved customer ID:
Stripe::Charge.create(
:amount => 1500,
:currency => "usd",
:customer => customer_id
)
Making a charge is outlined here in Stripe's documentation: https://stripe.com/docs/tutorials/charges
Q: And if so does Stripe accept feature requests?
A: I'm not 100% sure if Stripe accepts feature requests across all languages, but it is available for Go: https://github.com/stripe/stripe-go/blob/master/README.md#development
I'd double check the Development section of each README or contact a developer at Stripe directly (freenode #stripe)

Resources