Stripe: Use apple pay on the web for a subscription - javascript

In the documentation for setting up Apple pay with Stripe, the steps tell you to create a payment request with stripe elements in order to display the apple pay button - the example request is a one-time direct charge. You must have a payment request to display the button - so how can I create a payment request for a subscription? The payment request object is a stripe elements thing and is not described in the stripe api.
var elements = stripe.elements();
var prButton = elements.create('paymentRequestButton', {
paymentRequest: paymentRequest,
});
// Check the availability of the Payment Request API first.
paymentRequest.canMakePayment().then(function(result) {
if (result) {
prButton.mount('#payment-request-button');
} else {
document.getElementById('payment-request-button').style.display = 'none';
}
});
The flow for using a credit card is completely different. It doesn't require any payment request, you simply create a token from the stripe elements card form to create a customer.
The Stripe support page for Using Apple Pay for recurring payments just says "apple pay will create a token" but provides no clue how you would set it up without a one-time charge.
How can I make stripe display the apple pay button without requesting payment? If I have to request payment, is it just for one interval of the subscription, and will this amount be able to be billed on a recurring basis?

The payment request that you make with Stripe.js does not actually process a payment:
It simply confirms that the user's browser supports Apple/Google Pay, and displays a payment-sheet with the provided payment details.
After the user authorizes the payment described on the payment-sheet, Stripe will produce a payment method.
At this point, if you don't integrate the remaining steps, the user would never be charged - you would simply have a Stripe payment method ID.
Remaining steps you'd need to integrate at this point are:
Save the payment method ID to a Customer: https://stripe.com/docs/api/payment_methods/attach
Set the payment method as the default for subscription invoices: https://stripe.com/docs/api/customers/update (by setting invoice_settings.default_payment_method)
Subscribe the customer to a recurring Price (e.g., https://stripe.com/docs/billing/subscriptions/fixed-price)
You would trigger all of the above logic as a result of receiving the payment method from the payment request:
paymentRequest.on('paymentmethod', function(ev) {
const paymentMethodId = ev.paymentMethod.id;
// Send ID to your server to:
// a) attach it to a Customer
// b) set it as the default for subscription invoices
// c) create the subscription
});

Related

PayPal Donate SDK - Prefill Amount and Frequency

I am building an application which includes a custom donation form where users can select:
Frequency: monthly, single
Amount: 3 x Buttons with values, input for custom value
I am using the PayPal Donate SDK and cannot find a way to pass across the amount or frequency so that the amount is pre-filled and the "make this a monthly donation" checkbox selected/deselected based on the users input.
The PayPal button has been added to the page (just absolute styled over the form button) and the SDK opens the donation page in a modal which is my desired result.
This is the code to display my button:
window.PayPal.Donation.Button({
env: "sandbox",
hosted_button_id: "xxxxxxxxxxxx",
onComplete: function() {
// Redirect to success page, save the PP transaction details, etc.
}
}).render("#paypal-donate-button-container");
With the standard PayPal.Buttons API, I am able to pass in a createOrder function like so, where I can set the amount, for example;
window.PayPal.Buttons({
// ...
createOrder: function(data, actions) {
return actions.order.create({
purchase_units: [{
amount: {
value: document.querySelector(".selected-premium").dataset.value
},
reference_id: document.querySelector(".selected-premium").dataset.days + "-days"
}]
});
}
}
Is there a way to pass through the amount and frequency using the SDK, similar to how I can do it with the standard payments API? If not, what are the alternatives in 2022 that don't rely on SO answers that use docs that no longer exist/deprecated methods?
With the PayPal Donations flow (this includes the Donate SDK)
You can pass a parameter for the amount and currency_code. If you do pass a prefilled amount, an option to make the donation recurring will not be available.
You cannot pre select the option to make the donation recurring in the Donations flow.
For the case of recurring donations -- since it's not possible to precheck the option to make them recurring in the Donations flow, nor is it possible to prefill the amount and have that choice of recurrence even be available -- what you could do is instead use a Subscription flow for when a recurrence is selected, and have this render in a separate div container that is shown/hidden based on your monthly vs single selection. A subscribe button for your account can be generated at: https://www.paypal.com/billing/plans . The plan it uses must have a specific amount, but this can be overridden in the JS createSubscription function (based on whatever selection or amount was entered on your site) by (in addition to the base plan_id) adding a plan object that contains a billing_cycles object with the amount/frequency you want.

PayPal JavaScript SDK: Getting the Basic Card Info onApprove()

In PayPal JavaScript SDK, we get the details object onApprove as shown below:
onApprove: function (data, actions) {
console.dir(data);
// This function captures the funds from the transaction.
return actions.order.capture()
.then(function (details) {
console.dir(details);
// This function shows a transaction success message to your buyer.
alert('Transaction completed by ' + details.payer.name.given_name);
});
}
We noticed that the details object does not contain any information about the payment method that the payer used to make the payment, i.e. PayPal, Debit Card, or Credit Card, which of course, the last 4 digits card number isn't provided too.
Why we need the Basic Card Info?
We need the basic card info to generate a more useful receipt to our customers (including corporate customers). Without such information, it's useless for our customers to keep the receipt and for their accounting purposes because they can't even reference to which card of which bank that they were using for the payments.
Based on the PayPal Here docs, we found this from the Receipt API's response object:
"payment_card": {
"card_scheme": "CREDIT",
"card_number": "2677", // This is what we're looking for
"authorization_code": "087202",
"card_soft_description": "PP*PAYDIANTPAY",
"icc_info": {
"pin_present":false,
"signature_verified":false,
"authorization_response_code": "00",
"authorization_response_code_label": "APPROVED",
"icc_application_cryptogram": "606C700D55FB5C0A",
"icc_application_cryptogram_label": "TC",
"icc_application_identifier": "A0000000041010",
"icc_application_PAN_number": "01",
"terminal_id": "7688",
"transaction_status_information": "E800",
"issuer_application_data": "011060700222000014E100000000000000FF",
"terminal_verification_results": "0000008000"
}
}
But how can we get the same info with the JavaScript SDK of PayPal? I've also gone through the PayPal REST API but didn't seem to find it. Please advise, thank you.
If you integrate using the standard black Debit or Credit Card button, you will not receive any information about which card they used. In fact, you will not even know whether they paid with a card -- they might have fallen back to a regular PayPal checkout and used a different funding source. All billing information is kept private in PayPal by design.
If your country and currency are supported by advanced credit and debit card payments you could see about activating that for your account and integrate using that custom form (hosted fields) instead. This method will tell you the brand and last digits of the card in the details response.

React Paypal Buttons intent

I am using using react-paypal-button-v2 in my react app! i want to hold payment while my order is completed! i.e first complete the db transaction after that go fo paypal payment!
if i use paypal intent as authorize then it hold paymant but how later on it will pay after db transactio` in my react component!
here is my code but this method didn't work for me
onApprove(data, actions)
{
actions.order.capture();
}
<PayPalButton
options={paypalOptions}
amount="1.00"
onApprove={this.onApprove}
/>
When intent=authorize is used for an order, capturing the order will result in an authorization Payment object.
To capture that authorization Payment object, use the following API call: https://developer.paypal.com/docs/api/payments/v2/#authorizations_capture

stripe: Create a 30-day trial subscription charge on a saved card but allow user to upgrade and start charging immediately?

So before a user can create an account I want to save their credit card to charge a subscription with 30 day trial AND the ability to immediately charge the card for a subscription if the user demands it.
so my logic is to
1) create a customer
2) add payment details for customer
3) create subscription with 30 day trial
4) activate subscription upon user upgrade action
I'm not clear on how 4) is possible. I get that on 3), after 30 days, they are on a subscription. but what if the customer wants to start using the full version immediately before the trial is over, how would I create a charge for the subscription?
const stripe = require('stripe')('sk_test_asdfasdf');
(async () => {
// Create a Customer:
stripe.customers.create({
email: 'jenny.rosen#example.com',
payment_method: 'pm_1FWS6ZClCIKljWvsVCvkdyWg',
invoice_settings: {
default_payment_method: 'pm_1FWS6ZClCIKljWvsVCvkdyWg',
},
}, function(err, customer) {
// asynchronously called
});
//create subscription
stripe.subscriptions.create({
customer: 'cus_4fdAW5ftNQow1a',
items: [
{
plan: 'plan_CBXbz9i7AIOTzr',
},
],
expand: ['latest_invoice.payment_intent'],
}, function(err, subscription) {
// asynchronously called
}
);
})();
I'll chime in on this really quick, to hopefully get you in the right direction; This sounds like a case for Setup Intents. You can collect payment details, with the intent to charge at a later time. Since the trial won't incur any charges at first, all is good. However you work out the logic to switch from trial to active status on the subscription, you'd update the subscription end-date to end the trial.
This is nicely summarized here, for the most part, save for updating the Subscription and setting the trial_end argument:
https://stripe.com/docs/payments/save-and-reuse
API docs entry on updating the Subscription:
https://stripe.com/docs/api/subscriptions/update#update_subscription-trial_end
Once the trial is over, whether "naturally" or by explicitly setting the end timestamp, an invoice should be sent out or default payment method charged, depending on your settings. It wouldn't hurt to work in some good flow here, concerning user-experience; For example, having a confirmation step to let the customer know they are about to be charged X amount, before actually firing off that off.
Here are other helpful docs:
https://stripe.com/docs/saving-cards
https://stripe.com/docs/payments/setup-intents
https://stripe.com/docs/billing/subscriptions/trials
https://stripe.com/docs/billing/subscriptions/payment#handling-trial
https://stripe.com/docs/api/subscriptions/update

Stripe Connect Charge - Must authenticate as a connected account to be able to use customer parameter

I am trying to setup Stripe Connect and need to
charge the buyer by creating a customer first,
then generate a token and finally
charge the customer with this token.
This works fine as long as the buyer and seller are not the owners of the Stripe Connect Platform.
I.e. let's assume the following email corresponds to the account holder:
admin#admin.com
Now, we have two sellers:
seller_1#sellers.com
admin#admin.com
And we have one buyer:
buyer_1#buyers.com
My code works when buyer_1 buys from seller_1. All goes fine and an application fee is charged.
The problem however arises when buyer_1 wants to buy from admin#admin.com.
Eventhough admin#admin.com is connected to the account platform (I go through the same process as for seller_1), I keep getting the error:
message: "Must authenticate as a connected account to be able to use customer parameter. See https://stripe.com/docs/api#create_card_token for more details."
param: "customer"
raw: Object
rawType: "invalid_request_error"
requestId: "req_8EtIue0F4JWFmQ"
stack: 400
type: "StripeInvalidRequestError"
I use the following tutorial to save a customer and charge customers:
// store
// Set your secret key: remember to change this to your live secret key in production
// See your keys here https://dashboard.stripe.com/account/apikeys
var stripe = require("stripe")("SECRETKEY");
// (Assuming you're using express - expressjs.com)
// Get the credit card details submitted by the form
var tokenID = request.body.stripeToken;
// Create a Customer
stripe.customers.create({
source: tokenID,
description: "Example customer"
}, function(err, customer) {
});
// Create token
// Create a Token from the existing customer on the platform's account
stripe.tokens.create(
{ customer: CUSTOMER_ID, card: CARD_ID },
{ stripe_account: CONNECTED_STRIPE_ACCOUNT_ID }, // id of the connected account
function(err, token) {
// callback
}
);
I know this question is not recent but I have come across this same problem several times in my development testing.
The problem was fixed when I did a db:reset or removed the user(customer account) and reauthorized.
It turned out I had duplicate connect accounts for the same user, for old plans and the api_key was old.
Since I was in development and testing, I also found it useful to clear the test data from Stripe, on the dashboard >business settings >data > Delete all test data
Hope that helps.
Same thing happened to me. It's somewhat deceiving because Stripe let's you connect your account directly to the same account in the Settings (where it says "test the OAuth flow"), like a single account is acting as both the platform and the connected account. However, when you attempt to actually create charges or customers on the connected account, you get the above error.
I had this problem when testing charges using Stripe Connect. It turned out that when I went through the process of connecting a test business to my app (via the Connect To Stripe test page they provide) I was also already logged into my app's Stripe account in another browser window. This ended up saving my app's account data in the place of the new "test business" which kept causing charges to fail with that error.
When I went through the same process logged out of Stripe, it worked fine and charges were processed normally.
The answer was to simply change the customer id as the customer and the card is as source.
You can find the complete source code of a working example Stripe Connect with Ionic here:
https://www.noodl.io/market/product/P201601151251248/stripe-connect-guide-with-complete-source-code-all-you-need-to-start-accepting-money-on-behalf-of-others

Categories