Stripe Payment Method shows payment incomplete "required_payment_method" - stripe-payments

Here is my implementation
const paymentIntent = await stripe.paymentIntents.create({
amount: body.amount,
currency: 'gbp',
customer: customerId,
automatic_payment_methods: {
enabled: true,
},
application_fee_amount: applicationFeeData,
receipt_email: `${user.getDataValue('emailId')}`,
transfer_data: {
destination: merchant,
},
metadata: {
title: 'title',
startDate: 'startAt',
endDate: 'endAt',
actualAmount: body.actualAmount,
coupon: couponCode,
},
setup_future_usage: 'off_session',
});
I have passed "automatic_payment_methods" as I am not getting Payment Method Id as it is an instant payment, but it always fails and the dashboard shows me required_payment_method. But according to docs payment_method is an optional parameter. How to proceed without payment_method parameter in paymetnIntent?

A Payment Method object must be provided either during creation or confirmation (with Stripe.js) of the Payment Intent in order to facilitate the payment.
How you do this will depend on your integration, but the general recommendation is to collect payment information from your customer using the Payment Element which can then be used with the confirmPayment function.
I'd recommend following the Accept a payment guide which shows you how to build a full payment integration.

Related

Stripe email receipt subscription

I am following stripe's example for making subscriptions. I followed the example to where I got it to accept the payments. Sadly it is not sending an email receipt to the user that has made the payment. I went on to setting and allowed the emails. this has not done anything. I was reading in the docs that they don't send an email during the testing mode.
const price = await stripe.prices.retrieve('priceId')
const customer = await stripe.customers.create({
email: user.email,
name: `${user.firstname} ${user.surname}`,
})
const subscription = await stripe.subscriptions.create({
customer: customer.id,
items: [
{
price: price.id,
quantity,
},
],
payment_behavior: 'default_incomplete',
payment_settings: { save_default_payment_method: 'on_subscription' },
expand: ['latest_invoice.payment_intent'],
})
https://stripe.com/docs/billing/subscriptions/build-subscriptions?ui=elements&card-or-payment-element=card-element
You need to make sure the email is set on the Customer object:
To automatically send receipts, ensure that the customer’s email is set and the option email customers for successful payments is enabled in your email receipt settings.
See: https://stripe.com/docs/receipts#receipts-with-billing
If all this has been done, then I think you would need to reach out to Stripe support to find out what's going on.

Stripe recurring payment integrate with masterpass

Is there any way to take recurring payment with Masterpass using Stripe?
Google pay and Apple pay can take the recurring payment with Stripe by returning the card token for stripe process. Is there any way to get card token like this with Masterpass?
Yes you can, you'd create a PaymentMethod with the data you get back from Secure Remote Commerce (which is what Masterpass is calling itself now) and use that to start a subscription.
Follow Stripe's SRC guide, then when you get to the "complete the payment" part you'd do something this instead:
// create the payment method
const pm = await stripe.paymentMethods.create({
type: 'card',
card: {
masterpass: {
cart_id: cartId, // your unique cart ID
transaction_id: req.query.oauth_verifier, // get this from the SRC callback URL
},
}
});
// create the Stripe customer
const cust = await stripe.customers.create({
payment_method: pm.id,
});
// create the subscription
const sub = await stripe.subscriptions.create({
customer: cust.id,
items: [{
price: {{PRICE_ID}},
}],
default_payment_method: pm.id,
});

Stripe propagate paymentIntent description to Connected Account's transfer payment

I successfully created payment intents from a customer's card paying to a Standard Connected account using destination charge. In that payment intent created, I am specifying a description:
const paymentIntent = await stripe.paymentIntents.create({
amount: calculate_payment_amount(duration_minutes),
customer: "somet id",
currency: "usd",
description: `chat duration: 100`,
payment_method: paymentMethods.data[0].id,
payment_method_types: ['card'],
off_session: true,
confirm: true,
application_fee_amount: calculate_fee_amount(duration_minutes),
transfer_data: {
destination: "standard connected account ID",
},
metadata: {
metadata: "something
},
});
This payment displays the description if I view it from my platform's dashboard.
But if the standard connected account were to view this payment, the user won't be able to see the description (the same payment viewed from the standard account):
Is it possible to pass or propagate the same description of the payment intent to the same payment of the standard connected account?
Unfortunately, it doesn't look like it's currently possible to propagate the PaymentIntent description when creating destination charges. You would need to manually update the payment on the connected account with the description:
To do so, first, create the payment intent like you are doing now, except save the description as a standalone variable:
const paymentDescription = `chat duration: 100`;
const connectedAccountId = "acct_xyz";
const paymentIntent = await stripe.paymentIntents.create({
amount: calculate_payment_amount(duration_minutes),
customer: "somet id",
currency: "usd",
description: paymentDescription,
payment_method: paymentMethods.data[0].id,
payment_method_types: ['card'],
off_session: true,
confirm: true,
application_fee_amount: calculate_fee_amount(duration_minutes),
transfer_data: {
destination: connectedAccountId,
},
metadata: {
metadata: "something
},
});
Then, after the payment is confirmed, get the payment resulting from the transfer to the connected account:
const transfers = await stripe.transfers.list({
destination: connectedAccountId,
transfer_group: paymentIntent.transfer_group,
});
const paymentId = transfers.data[0].destination_payment;
The key above is that when you do a destination charge, Stripe will create a transfer and a payment (in the form of a Charge) to the connected account in the background. Here we're getting the transfer associated with the payment intent, and from that getting the associated payment. This is the py_xyz ID that you see when viewing the payment in the connected account's dashboard.
Then, update the payment to include the description:
const updatedPayment = await stripe.charges.update(
paymentId,
{
description: paymentDescription,
},
{
stripeAccount: connectedAccountId,
}
);
At that point the description will show in the standard account's payment view:

Stripe create a direct charge node.js

I am trying to create a direct charge to a standard Stripe connected account from a node.js backend. The codes I wrote are:
async function create_direct_charge(language_learner_id, native_speaker_id, call_duration) {
try {
const customer_id = "xxxxxx";
const connected_standard_account_id = "xxxxxx;
const paymentMethods = await stripe.paymentMethods.list({
customer: customer_id,
type: 'card',
limit: 1,
});
const paymentMethod = paymentMethods.data[0].id;
const paymentIntent = await stripe.paymentIntents.create({
payment_method_types: ['card'],
payment_method: paymentMethod,
amount: 1000,
customer: customer_id,
currency: "cad",
off_session: true,
confirm: true,
application_fee_amount: 100,
}, {
stripeAccount: connected_standard_account_id,
});
}
catch (error) {
console.log(error);
}
}
The above codes generate an error of: No such PaymentMethod: 'pm_xxxxxx'; OAuth key or Stripe-Account header was used but API request was provided with a platform-owned payment method ID. Please ensure that the provided payment method matches the specified account.
The thing is that the customer with the customer_id already has a valid payment method attached:
The payment method is valid, since I was able to create a destination charge with that payment method. The payment is not set as the default source though. I am wondering if that is the problem. What did I do wrong here?
The payment method is valid, since I was able to create a destination charge with that payment method.
That tells me that the PaymentMethod (e.g. pm_123) was created on the Platform Stripe account and hence lives there.
So when tell Stripe to "Charge pm_123 on Connect account acct_1 as a Direct Charge", that won't work as the PaymentMethod object pm_123 doesn't exist on the Connect account, it exists on the Platform account.
In order to get this to work, you have to first "clone" the PaymentMethod pm_123 to the Connect account, then create a Direct Charge with this newly cloned PaymentMethod token, as explained here: https://stripe.com/docs/payments/payment-methods/connect#cloning-payment-methods

How to attach a payment method with Stripe?

I'm struggling to get Stripe to work on my server.
So, on the client side, I have this code (after much struggle to get element working) :
this.props.stripe.createPaymentMethod({ type: 'card', card: cardElement, billing_details: { name: name } }).then((paymentMethod) => {
// server request with customer_id and paymentMethod.id);
});
This works fine. Now, on the server (NodeJS), I want to add a new on-going subscription with a fixed fee for my customer.
Here's what I have :
const paymentIntent = await stripe.paymentIntents.create({
amount: 1000,
currency: 'usd',
payment_method_types: ['card'],
customer: req.body.customer_id,
metadata: { integration_check: 'accept_a_payment' },
});
const paymentIntentConfirmation = await stripe.paymentIntents.confirm(paymentIntent.id, { payment_method: req.body.paymentMethod_id });
const newSubscription = await stripe.subscriptions.create({
customer: req.body.customer_id,
items: [{ plan: premium_plan.id, quantity: 1 }],
default_payment_method: req.body.paymentMethod_id,
});
const attachPaymentToCustomer = await stripe.paymentMethods.attach(req.body.paymentMethod_id, { customer: req.body.customer_id });
const updateCustomerDefaultPaymentMethod = await stripe.customers.update(req.body.customer_id, {
invoice_settings: {
default_payment_method: req.body.paymentMethod_id,
},
});
So, if I don't attach the payment to customer, I get the following error message :
'The customer does not have a payment method with the ID pm_1Gx9m1HVGJbiGjghYhrkt6j. The payment method must be attached to the customer.'
If I do, I get the following error message :
'This PaymentMethod was previously used without being attached to a Customer or was detached from a Customer, and may not be used again.'
So, how do I add the damn payment method, so when I retrieve my customer, it shows this customer has been updated with a new subscription to the service he just subscribed to, together with his payment method (a CC in this case).
Any help here for a frustrated user is very appreciated !
On a more general note, implementing Stripe has been a very painful experience so far. Nothing seems to work. I use Typescript and there are so many bugs. The documentation is not very helpful and not well explained. "Create a source", "create a token", "create a payment intent", "create a setup intent", how am i supposed to understand the difference between all these things ? I want to add a god damn online subscription, which should be quite a standard procedure for an Internet service. Why are there so many different guidelines, with tokens, with sources, etc....
There's a few changes you can make here to get it working, in order to start a Subscription [1] you don't need to create and confirm a PaymentIntent. That is created automatically inside the Invoice(s) as they're created for payment. So the steps roughly are (you've done a lot of this already but just to have an end to end example):
Create a customer
Collect the payment information securely using Stripe.js
Attach the PaymentMethod to the Customer
(Optionally) save that as the invoice settings default payment method (because you can pass the PaymentMethod to the Subscription creation as a default payment method, but it's good practice so that you can start Subscriptions for that Customer with the same payment method)
Create a Subscription
Provision your service
Take into account SCA/3DS and handle authentication [2]
That's outlined in detail on [1]. Here's some sample code to get the Subscription started, you can replace the calls that create products and prices with your own IDs of course:
const customer = await stripe.customers.create({
name: "Foo Bartley"
});
const paymentMethod = await stripe.paymentMethods.create(
{
type: 'card',
card: {
number: '4242424242424242',
exp_month: 6,
exp_year: 2021,
cvc: '314',
},
}
);
const product = await stripe.products.create(
{name: 'Gold Special'}
);
const price = await stripe.prices.create(
{
unit_amount: 1111,
currency: 'eur',
recurring: {interval: 'month'},
product: product.id,
}
);
// Everything above here is just setting up this demo
const attachPaymentToCustomer = await stripe.paymentMethods.attach(
paymentMethod.id, // <-- your payment method ID collected via Stripe.js
{ customer: customer.id } // <-- your customer id from the request body
);
const updateCustomerDefaultPaymentMethod = await stripe.customers.update(
customer.id, { // <-- your customer id from the request body
invoice_settings: {
default_payment_method: paymentMethod.id, // <-- your payment method ID collected via Stripe.js
},
});
const newSubscription = await stripe.subscriptions.create({
customer: customer.id, // <-- your customer id from the request body
items: [{ plan: price.id, quantity: 1 }], // <-- plans and prices are compatible Prices is a newer API
default_payment_method: paymentMethod.id, // <-- your payment method ID collected via Stripe.js
});
Hope this helps!
[1] https://stripe.com/docs/billing/subscriptions/fixed-price#create-subscription
[2] https://stripe.com/docs/billing/subscriptions/fixed-price#manage-payment-authentication

Resources