PayPal Donate SDK - Prefill Amount and Frequency - javascript

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.

Related

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.

Stripe: Use apple pay on the web for a subscription

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
});

How to create discrete inputs for credit card information with the Vue Stripe Checkout library?

Shown in an example screenshot on its GitHub page, Vue Stripe Checkout library displays a credit card input form with individual inputs for the card information (CC#, expiration, CVV) and also the name, country, and email:
Based on the Vue Stripe Elements example shown in the GitHub README.md, my single-file Vue component currently creates a single input for all the credit card information. It looks like this:
And this is the code that created it:
<template>
<div>
<StripeElements
ref="elementsRef"
:pk="publishableKey"
:amount="amount"
#token="tokenCreated"
#loading="loading = $event"
>
</StripeElements>
<button #click="submit">Pay ${{ amount / 100 }}</button>
</div>
</template>
<script>
import { StripeElements } from "vue-stripe-checkout";
export default {
components: {
StripeElements
},
data: () => ({
loading: false,
amount: 1000,
publishableKey: process.env.VUE_APP_PUBLISHABLE_KEY,
token: null,
charge: null
}),
methods: {
submit() {
this.$refs.elementsRef.submit();
},
tokenCreated(token) {
this.token = token;
// for additional charge objects go to https://stripe.com/docs/api/charges/object
this.charge = {
source: token.id,
amount: this.amount, // the amount you want to charge the customer in cents. $100 is 1000 (it is strongly recommended you use a product id and quantity and get calculate this on the backend to avoid people manipulating the cost)
description: this.description // optional description that will show up on stripe when looking at payments
}
this.sendTokenToServer(this.charge);
},
sendTokenToServer(charge) {
// Send to charge to your backend server to be processed
// Documentation here: https://stripe.com/docs/api/charges/create
console.log(charge)
}
}
};
</script>
<style lang="scss" scoped></style>
However, after scouring its documentation, limited examples (here and its source code), and Issues section, I am unclear on how a credit card input form with individual inputs for the card information (CC#, expiration, CVV) and also the name, country, and email can be created. I am hoping someone with experience with Stripe might be able to shed some light.
Unfortunately, it's not possible to create separate card number, expiry, and cvc inputs in the current version of Vue Stripe Checkout.
The library's Stripe Elements component creates a Card Element under the hood as you can see here:
https://github.com/jofftiquez/vue-stripe-checkout/blob/master/src/Elements.vue#L84
This means that the component will include the card number, expiry, and cvc inputs combined, as shown in your second screenshot. As far as I can tell, the library has no components or options to create discrete card number, expiry, and cvc inputs which would require making three distinct Stripe Elements as shown here: jsfiddle.net/3p89x9gL
The first screenshot is an image of Stripe Checkout which is a product built by Stripe. The idea is that you add a button to your site which redirects to a form hosted by Stripe and they handle the rest. In this case, the library has a component that makes it easy to redirect to Stripe Checkout:
https://github.com/jofftiquez/vue-stripe-checkout#vue-stripe-checkout-1

Is there any way to render freshservice app on portal pages (Requesters view)

My Requirement is
1. User will type subject.
2. On the basis of subject, I want to call third party rest API (Currently being blocked by CORS. even the jsonp request is also not working)
3. I want to set some field values on form according to the response
You cannot render an Freshservice app from the customer's view (User/Employee/Requester) as of now. Instead you can create Freshservice app on Agent portal where tickets are managed.
Create a serverless app.
On onTicketCreate product event you can write in your logic in server.js:
exports = {
events: [{
event: "onTicketCreate",
callback: "onTicketCreateCallback"
}],
onTicketCreateCallback: function(payload) {
console.log("Logging arguments from onTicketCreate event: " + JSON.stringify(payload));
// 1.Implement the logic with the help of payload's ticket subject that you are looking for.
// 2. To shoot bypass CORS use platform's request API - https://developers.freshservice.com/docs/request-api/
// 3. Update the Fields using - https://api.freshservice.com/v2/#view_a_change
}
}
See this reference for making changes to agent facing field values.
In simple terms this process results to fill in fields as per your use case. Only difference is, it happens on creating a ticket but not while filling up the requester facing form.

Using Negative Testing via Paypal Express Checkout client-side JS button implementation

I'm currently working on a PayPal Express checkout integration using the Client-side JS approach for taking payments. I'm looking to utilise their "Negative Testing" feature to try to simulate potential errors and provide appropriate responses to the customer.
Just a reference to the relevant doc page here for reference
It seems to enable negative testing you need to pass an extra header along with the the payment request specifying the particular error you would like to trigger for that payment.
This is my current JS for setting up the transaction:
<script>
//We need to convert our generated json string into a bonified javascript object
var paypal_transaction = JSON.parse(JSON.stringify(<?php echo $paypal_json; ?>));
paypal.Button.render({
env: 'sandbox', // 'production'/'sandbox',
commit: true, // Show a 'Pay Now' button - Allows us to capture the payment right away
client: {
sandbox: 'Ab_hPp7h70DoFKChLMSynNxacQQbGcb_tP1cDbzW9jC6a0rYIZH0CkEYYfkw6csvmlyTmfLnagelqB85',
production:''
},
//How we want the button to look
style: {
size: 'responsive',
color: 'gold',
shape: 'rect',
label: 'pay'
},
headers: {
'{"mock_application_codes":"INSTRUMENT_DECLINED"}'
}
payment: function(data,actions) {
return actions.payment.create({
//Pass our created transaction to paypal.
payment:paypal_transaction,
/**
* We have to set the following fields to prevent the client from
* changing their delivery address when they're at PayPal
*/
experience: {
input_fields: {
no_shipping: 0,
address_override:1
},
}
});
},
onAuthorize: function(data, actions) {
/**
* [description]
* #param payment - The authorised transaction returned from paypal
* #return redirect - We redirect the cutomer to our confirmation page as soon as we return from PayPal as we're confident we have the correct
*/
return actions.payment.execute().then(function(payment) {
actions.redirect();
});
},
onError: function(err) {
console.log(err);
// Show an error page here, when an error occurs
},
onCancel: function(data, actions) {
return actions.redirect();
// Show a cancel page or return to cart
}
}, '#paypal-button');
Essentially my question is where do I specify the mock application codes like this in the above implementation.
In the docs they give an example cURL request with the below as the extra header that needs to be passed:
"PayPal-Mock-Response:{\"mock_application_codes\":\"INSTRUMENT_DECLINED\"}"
I just don't know how to do this via the JS approach. Can negative testing only be used with a server side implementation?
Hope that's all clear enough!
Had similar issue myself, and the official answer I got was that it is not available:
"I understand this is a frustrating situation. Unfortunately we do not
have any way to offer negative testing for client side integrations.
It may possible for you to do so using Postman, however, we do not
have documentation to offer."
This is really sad though, other payment providers have fixed card numbers for certain error scenarios for example, or have special payment value based codes. PayPal only has that for the Payflow integration, and the request header based mocking stuff is also only possible if you are directly calling their REST APIs.
PayPal is really lame in these aspects, as even if you are mocking behavior with server integration (not that hard, for this at least they have proper code examples), this mocking is explicit and you control the error. If it would be implicit, and originate from an actually validated but invalid card for example, it would be more realistic.

Categories