How to implement paypal buttons for recurring payment without subscription plan - recurring

As my website will allow coupon also so my subscription plan amount can be vary with respect to coupon and each time creating new plan is not ideal way
is there any way to pass duration here
// Sets up the transaction when a payment button is clicked
createOrder: function(data, actions) {
return actions.order.create({
purchase_units: [{
amount: {
value: '77.44' // Can reference variables or functions. Example: `value: document.getElementById('...').value`
}
}],
stored_payment_source: [{payment_type:'RECURRING'}]
});
},
?

Related

How to test recurring payment on stripe subscription for due bill?

I have created subscription using stripe api for 1 month interval.
const subscription = await stripe.subscriptions.create(
{
customer: customer.id,
items: [
{
price: productPrice.id,
},
],
// payment_behavior: 'default_incomplete',
expand: ['latest_invoice.payment_intent'],
application_fee_percent: fee,
},
{
stripeAccount: accountId,
}
);
Subscription created successfully based on product and price.but i can't wait for 1 month (next billing) for testing so i need to test now how will work for next payment.it will auto deduct from payment method? or customer will notify about next due and have to pay? there need more code for it?
Stripe has a feature called Test Clocks that allows to move subscriptions forward in time. So you could create a subscription with a test clock, then advance the clock by one month to see exactly what happens.
But to answer your question: if the customer (or the subscription) has a default payment method set, then yes Stripe will automatically attempt to make a payment at the end of every billing cycle.

Stripe Node.js - How to split a payment between several beneficiaries (connected accounts)?

For my first implementation, I transfer the amount of the transaction directly to a beneficiary from a paymentMethod Id retrieved from my app (Flutter). Now my goal would be to split the payment between several beneficiaries on the same transaction.
First implementation code:
var clonedPaymentMethod = await stripe.paymentMethods.create(
{
payment_method: paym,
},
{
stripeAccount: stripeVendorAccount,
}
);
var paymentIntent = await stripe.paymentIntents.create(
{
amount: amount,
currency: currency,
payment_method: clonedPaymentMethod.id,
confirmation_method: "automatic",
confirm: true,
application_fee_amount: fee,
description: "desc",
},
{
stripeAccount: stripeVendorAccount,
}
);
const paymentIntentReference = paymentIntent;
By checking the documentation, I noticed that the stripe.paymentMethods.create method was no longer specified, and that the stripe.transfers.create methods were added.
This code is attempting to clone a payment method to a connected account and then create a direct charge on that account. In order to create charges and then to split the funds of that charge to separate connected accounts a different approach would be needed. The model would be closer to "Separate charges and transfers", where the charge is made on that platform and then some amounts are shared among the connected accounts using transfers. A full description is outlined here [1].
[1] https://stripe.com/docs/connect/charges-transfers

Once off payment with Stripe using the API ID

I have created a subscription service using Stripe. I can subscribe a user to use recurring payments. This is the relevant code (node):
// Create the subscription
const subscription = await stripe.subscriptions.create({
customer: req.body.customerId,
items: [{ price: req.body.priceId }],
expand: ['latest_invoice.payment_intent'],
});
This works and uses the priceId as shown in the dashboard:
However, it falls over when I sell a product which isn't recurring. I get the error:
The price specified is set to `type=one_time` but this field only accepts prices with `type=recurring`
I understand the error, but I am not sure if I can set a subscription to not be recurring.
My app has 3 tiers:
once off
monthly
yearly
Ideally, I would like not to add a whole new section of code to handle what seems like a subset of what subscriptions do, but even if I do, the paymentIntent object seems to only take an amount rather than the API ID as shown in the picture. Is there any way to do this using the infrastructure I have already built?
You can't create a subscription with a non-recurring price, instead for one-off payments you'd use a PaymentIntent.
Prices are meant for use with subscriptions and the Checkout product, but you can still use the data in them for PaymentIntents. For instance:
// get the price
const price = await stripe.prices.retrieve(req.body.priceId);
// check if the price is recurring or not
if (price.recurring !== null) {
// Create the subscription
const subscription = await stripe.subscriptions.create({
customer: req.body.customerId,
items: [{ price: req.body.priceId }],
expand: ['latest_invoice.payment_intent'],
});
// do something with the subscription
} else {
const pi = await stripe.paymentIntents.create({
customer: req.body.customerId,
currency: 'usd',
amount: price.unit_amount,
});
// do something with the PaymentIntent
}
you can also attach one-time items via the subscription.create call by placing them in add_invoice_items.
see: https://stripe.com/docs/api/subscriptions/create?lang=node#create_subscription-add_invoice_items

PayPal subscription and webhooks

I made an website with a service that I am charging for. I want to create a PayPal subscription. I need that subscription to be connected with my backend (firebase functions - node.js) so I can change some data in the database to serve my users different content depending if they are paying or not. I wanted to use PayPal buttons for my subscription but I can't find a way to connect that button with my backend so it seems PayPal buttons aren't optimal for my problem. I can't use Stripe because it's not supported in my country. Can you offer me a different solution for my subscripton payments or show how can I use PayPal?
You can use Paypal Node SDK for your use case instead of relying to the embeddable Paypal subscribe button. The SDK will give you better integration with NodeJs.
There are basically 2 steps to do this:
1.) Define the Billing Plan Object
The billing plan object defines the subscription plan, including the number of cycles, frequency of payment, any setup fees, and so on.
var billingPlanAttribs = {
name: 'Food of the World Club Membership: Standard',
description: 'Monthly plan for getting the t-shirt of the month.',
type: 'fixed',
payment_definitions: [{
name: 'Standard Plan',
type: 'REGULAR',
frequency_interval: '1',
frequency: 'MONTH',
cycles: '11',
amount: {
currency: 'USD',
value: '19.99'
}
}],
merchant_preferences: {
setup_fee: {
currency: 'USD',
value: '1'
},
cancel_url: 'http://localhost:3000/cancel',
return_url: 'http://localhost:3000/processagreement',
max_fail_attempts: '0',
auto_bill_amount: 'YES',
initial_fail_amount_action: 'CONTINUE'
}
};
Of course, you will need to change cancel_url and return_url to your actual Firebase functions endpoints (or localhost if you are running your functions in localhost for development purposes)
2.) Create and Activate Billing Plan, so once you created or defined your billing - you will need to create that object and activate the billing plan like so:
paypal.billingPlan.create(billingPlanAttribs, function (error, billingPlan){
var billingPlanUpdateAttributes;
if (error){
console.error(JSON.stringify(error));
throw error;
} else {
// Create billing plan patch object
billingPlanUpdateAttributes = [{
op: 'replace',
path: '/',
value: {
state: 'ACTIVE'
}
}];
// Activate the plan by changing status to active
paypal.billingPlan.update(billingPlan.id, billingPlanUpdateAttributes, function(error, response){
if (error){
console.error(JSON.stringify(error));
throw error;
} else {
console.log('Billing plan created under ID: ' + billingPlan.id);
}
});
}
});
Again, all of these are documented in Paypal's Developer Section.
Here's also a link to their github example using NodeJs (which is same underlying backend as a Firebase Function)

Stripe v3 - SetupIntents and Subscriptions

I'm trying to use SetupIntents to validate and save a Payment Method and then create a Subscription using it to charge the customer (inmediately and then monthly) for the required amount.
This appears to be working fine:
The Card is validated (including SCA if needed)
The Payment Method is created, attached to customer as default and enabled for future usage with the status SUCEEDED.
The Subscription is created and uses the above payment method
The problem is that Stripe then generates the corresponding Invoice and Payment Intent but the latter with the status "requires_action" whenever the provided Card requires Secure Customer Authorization (SCA), even though the right payment method (enabled for future usage) is being used and the card validation has been already performed.
I thought the whole point of using SetupIntents was precisely to validate the payment method beforehand and be able to charge the customer afterwards.
Is my assumption simply wrong or this is actually possible and I might just be missing something?
Thanks in advance
EDIT: This is the subscription creation code in the backend:
# Set the default payment method on the customer
Stripe::Customer.update(
stripe_customer_id,
invoice_settings: {
default_payment_method: #requested_source
}
)
subscription = Stripe::Subscription.create({
"customer" => stripe_customer_id,
"proration_behavior" => 'create_prorations',
"items" => [
[
"plan" => "#{#stripe_plan_api_id}",
],
],
'default_tax_rates' => [
"#{#stripe_tax_rate_id}",
],
"expand" => ["latest_invoice.payment_intent"]
});
Thanks for the question, Eduardo.
There are a couple ways to create a Subscription while gaining the Customers SCA authentication and permission to charge the card later. Assuming we already have a Stripe Customer object created and their ID is stored in stripe_customer_id. With the flow you have now there are a couple steps:
Create the SetupIntent. Note that if you create it with usage: 'off_session' and the Customer it'll attach the resulting PaymentMethod when confirmed.
setup_intent = Stripe::SetupIntent.create({
customer: stripe_customer_id,
usage: 'off_session',
})
Collect payment details and confirm the SetupIntent using its client_secret on the client which will attach the PaymentMethod to the customer. Note that it will attach but will not be set as the invoice_settings.default_payment_method by default, so you'll need to make a separate API call later to update the Customer (see step 3).
stripe.confirmCardSetup(
'{{setup_intent.client_secret}}',
{
payment_method: {
card: cardElement,
},
}
).then(function(result) {
// Handle result.error or result.setupIntent
});
Update the Customer and set its invoice_settings.default_payment_method equal to the ID of the PaymentMethod on the successfully confirmed SetupIntent.
Stripe::Customer.update(
stripe_customer_id, {
invoice_settings: {
default_payment_method: 'pm_xxxx', # passed to server from client. On the client this is available on the result of confirmCardSetup
}
})
Create the Subscription with off_session: true
subscription = Stripe::Subscription.create({
customer: stripe_customer_id,
proration_behavior: 'create_prorations',
items: [{
plan: "#{#stripe_plan_api_id}",
}],
default_tax_rates: [
"#{#stripe_tax_rate_id}",
],
expand: ["latest_invoice.payment_intent"],
off_session: true,
})
This uses what's called a "Merchant Initiated Transaction" (MIT) for the Subscription's first payment. This is technically okay if the Subscription is created later after the Customer leaves and should technically work.
If the customer is on your site/app when you create the Subscription, there's another flow that is a bit more correct and doesn't require using a MIT exemption for SCA. The flow is the following for a Subscription without a trial:
Collect card details with createPaymentMethod on the client (no SetupIntent)
stripe.createPaymentMethod({
type: 'card',
card: cardElement,
}).then(function(result) {
//pass result to your server.
})
Attach those card details to the Customer
Stripe::PaymentMethod.attach(
"pm_xxx", {
customer: stripe_customer_id
}
)
Update the Customer's invoice_settings.default_payment_method
Stripe::Customer.update(
stripe_customer_id,
invoice_settings: {
default_payment_method: #requested_source
}
)
Create the Subscription (without off_session: true)
subscription = Stripe::Subscription.create(
customer: data['customerId'],
items: [
{
price: 'price_H1NlVtpo6ubk0m'
}
],
expand: ['latest_invoice.payment_intent']
)
Use the Subscription's latest_invoice's payment_intent's client_secret to collect payment details and confirm on the client.
stripe.confirmCardPayment(
'{{subscription.latest_invoice.payment_intent.client_secret}}', { ......
This second payment flow is a bit more correct from an SCA standpoint for getting authorization to charge the card. The second approach is outlined in the guide here: https://stripe.com/docs/billing/subscriptions/fixed-price
We also have a Stripe Sample you can use to experiment here: https://github.com/stripe-samples/subscription-use-cases/tree/master/fixed-price-subscriptions

Resources