Paypal Express Checkout - Authorization not appearing in dashboard - javascript

I am creating & sending the following payment via the Express checkout API V4:
return paypal.rest.payment.create(env, client, {
intent: 'authorize',
payer: {
"payment_method": "paypal"
},
transactions: [
{
amount: { total: '0.01', currency: 'GBP' }
}
]
});
and I'm returning the following object:
Which all seems to be on the right track. The problem is, there is no sign of this payment auth in the sandbox dashboard.
I've even tried using a live account, and sending a real penny, but there is no sign of the transaction in either the buyer or seller account.
If this payment is not being successfully created, why am I seeing the object returned with a state of "created"?
FYI: If I send a payment using intent: 'sale' it processes successfully and appears in the dashboard.

I had the same problem. API and documentation of PayPal is something awful...
The logic is this:
1. You have to make execute payment.
I tried to do it in different ways, but the easiest way ended up like this:
In the examples on the Paypal site show your complete code with onAuthorize: function(data, actions) , so this function should look like this:
onAuthorize: function(data, actions) {
return actions.payment.get().then(function(payment) {
console.log(payment);
var b = payment.payer;
var bb = b.payer_info;
// alert (bb.payer_id);
var newUrl = "http://YOURDOMAIN.COM/execute.php?paymentId="+payment.id+"&token=EC-"+payment.cart+"&PayerID="+bb.payer_id;
console.log(newUrl);
// go to the execute.php and send to paypal payment confirmation
window.location.replace(newUrl);
});
}
Once you got the object with a transaction you must still confirm it!
Go here https://github.com/paypal/PayPal-PHP-SDK/wiki/Installation download the PHP SDK, it will need to file execute.php to easily confirm the payment and it showed up in the admin panel PayPal. I downloaded the SDK for a direct link, without Composer.
Then in the newly created file execute.php connect this directly SDK without Composer.
// Use below for direct download installation
require __DIR__ . '/PayPal-PHP-SDK/autoload.php';
Then copy the contents of the file itself execute.php and replace it PayPal client ID and client secret. Full code of execute.php here http://pastebin.com/K750qcxE
I couldn't paste here all the code. Citation of code here is terribly implemented, as well as PayPal API :)
p.s. in the script I sent to return url, but I don't know why paypal did not redirect me to it, so I redirect using javascript when you get the transaction object.
sorry for my english

Related

Stripe Checkout Subscription Payment failure redirects to Expire Link Page

I'm trying to integrate Stripe One time and Subscription Payment using their Checkout API.
I have also enabled 3D secure payments.
In one time payment when payment is successful it redirects to our success page. And when a payment is failed, it shows error message in checkout form. Which is as expected.
In Checkout subscription, when payment is successfully it perfectly redirects to success page. For failed payment it also shows error messages after 3D authentication, but when I try to pay with another card or the same card after a failed attempt, it redirects me to Expired link page.
I checked in stripe demo checkout page (https://checkout.stripe.dev/preview) where it works fine but don't know what I'm missing.
What I understand from the stripe docs is that, for failed payment I should handle error and tell users/redirects to use a different payment method.
I have registered the following webhook events:
invoice.payment_action_required
charge.failed
customer.subscription.deleted
customer.subscription.created
checkout.session.completed
invoice.paid
When invoice.payment_action_required event is triggered, I have to manually confirm the payment for 3D secure authentication (it's required for subscription). I have written the following code to confirm the payment.
if (paymentIntent.status === 'requires_action') {
await stripe.paymentIntents.confirm(payment_intent);
}
Here is the code snippet to create a subscription session:
const session = await stripePrivate.checkout.sessions.create({
mode: 'subscription',
payment_method_types: ['card'],
line_items: [
{
price: planId,
quantity: 1
}
],
metadata: {
transactionId
},
subscription_data: {
metadata: {
transactionId
}
},
success_url: `${merchantCallbackURL}?sessionId={CHECKOUT_SESSION_ID}&status=success&orderId=${orderId}`,
cancel_url: `${merchantCallbackURL}?sessionId={CHECKOUT_SESSION_ID}&status=canceled&orderId=${orderId}`
});
const callbackUrl = session.url;
And below is the page, I'm redirected to if a subscription payment is failed (from 2nd attempt):
Here I'm adding some checkout URL for testing:
Test card 1: 4000008260003178 (insufficient balance)
Test card 2: 4000002500003155
https://checkout.stripe.com/pay/cs_test_a1SAsf7YCjXOZPNKf0K9AXNDHSm8lMLFwD80VZEajKxEAgpeD9GiZBH2wr#fidkdWxOYHwnPyd1blpxYHZxWjA0TGF0TDFDQWA3QFN8cm9dRjBzRk1tVHxEfHBHbnBJf280clBGblNsX0NSMGE2bGY1QFdsYktWaUY2M0JTN1dATERKaEBXcExGf1VBTzxKdz1%2FM3RmSjVxNTVJf1dTY3NmRycpJ2N3amhWYHdzYHcnP3F3cGApJ2lkfGpwcVF8dWAnPyd2bGtiaWBabHFgaCcpJ2BrZGdpYFVpZGZgbWppYWB3dic%2FcXdwYHgl
https://checkout.stripe.com/pay/cs_test_a1RTXGddpYeZy0zRfvuJrGWqtT3KiURrJFCjSDS9fK8OIhdmTPFBD0Mzx8#fidkdWxOYHwnPyd1blpxYHZxWjA0TGF0TDFDQWA3QFN8cm9dRjBzRk1tVHxEfHBHbnBJf280clBGblNsX0NSMGE2bGY1QFdsYktWaUY2M0JTN1dATERKaEBXcExGf1VBTzxKdz1%2FM3RmSjVxNTVJf1dTY3NmRycpJ2N3amhWYHdzYHcnP3F3cGApJ2lkfGpwcVF8dWAnPyd2bGtiaWBabHFgaCcpJ2BrZGdpYFVpZGZgbWppYWB3dic%2FcXdwYHgl
https://checkout.stripe.com/pay/cs_test_a1ZMzrim1XQWNVgHCceiSw9mjrtMMdTricwdGhzf7wdHYcEsSabFTxRGcv#fidkdWxOYHwnPyd1blpxYHZxWjA0TGF0TDFDQWA3QFN8cm9dRjBzRk1tVHxEfHBHbnBJf280clBGblNsX0NSMGE2bGY1QFdsYktWaUY2M0JTN1dATERKaEBXcExGf1VBTzxKdz1%2FM3RmSjVxNTVJf1dTY3NmRycpJ2N3amhWYHdzYHcnP3F3cGApJ2lkfGpwcVF8dWAnPyd2bGtiaWBabHFgaCcpJ2BrZGdpYFVpZGZgbWppYWB3dic%2FcXdwYHgl
https://checkout.stripe.com/pay/cs_test_a1iheiAZbEXl3hhuVPBSNARja4XkYL2su4bt0JRqlNQMaVnd4V2Hg5BEWD#fidkdWxOYHwnPyd1blpxYHZxWjA0TGF0TDFDQWA3QFN8cm9dRjBzRk1tVHxEfHBHbnBJf280clBGblNsX0NSMGE2bGY1QFdsYktWaUY2M0JTN1dATERKaEBXcExGf1VBTzxKdz1%2FM3RmSjVxNTVJf1dTY3NmRycpJ2N3amhWYHdzYHcnP3F3cGApJ2lkfGpwcVF8dWAnPyd2bGtiaWBabHFgaCcpJ2BrZGdpYFVpZGZgbWppYWB3dic%2FcXdwYHgl
https://checkout.stripe.com/pay/cs_test_a1iheiAZbEXl3hhuVPBSNARja4XkYL2su4bt0JRqlNQMaVnd4V2Hg5BEWD#fidkdWxOYHwnPyd1blpxYHZxWjA0TGF0TDFDQWA3QFN8cm9dRjBzRk1tVHxEfHBHbnBJf280clBGblNsX0NSMGE2bGY1QFdsYktWaUY2M0JTN1dATERKaEBXcExGf1VBTzxKdz1%2FM3RmSjVxNTVJf1dTY3NmRycpJ2N3amhWYHdzYHcnP3F3cGApJ2lkfGpwcVF8dWAnPyd2bGtiaWBabHFgaCcpJ2BrZGdpYFVpZGZgbWppYWB3dic%2FcXdwYHgl
Above URL will be expired within 24 hours. Please ask if you need
another active url for testing.
How to test?
Use the given test card 1 and complete 3D authentication
Now use test card 1 or 2 and try to subscribe again, you'll be redirected to Expired link page
How do I fix this issue? What am I missing here?
Checkout pages are single use. If you use one to create a subscription, it is then "consumed" and can't be used again.
It sounds like you're trying to deal with the case where a subscription is created, but a future invoice's payment fails due to the payment being in the requires_action status. This will happen if the card in question requires 3DS and must be confirmed on the client by the user. See the PaymentIntents flow: https://stripe.com/docs/payments/intents
You wouldn't redirect to the same Checkout session to action a card in the requires_action status, instead you'd either build your own UI or use the Customer portal: https://stripe.com/docs/billing/subscriptions/customer-portal.

Handling response from HTTP POST without access to the request in Next.js

I'm implementing the payment gateway API of a local company that provides a HTML fragment that renders a button in my page to handle the checkout and payment in a modal-like interface that is out of my control (without redirecting the user outside of my page).
The fragment is a script tag like this:
<form action="http://localhost:3000/api/checkout" method="POST">
<script
src="https://www.mercadopago.com.ar/integrations/v1/web-tokenize-checkout.js"
data-public-key="ENV_PUBLIC_KEY"
data-transaction-amount="100.00">
</script>
</form>
After the Card and payment info is entered by the user, the gateway makes a POST request to my API endpoint 'checkout' in Next.js (specified in the action attribute of the form) with some data to confirm the transaction as shown in the following.
/pages/api/checkout.js:
export default (req, res) => {
mercadopago.configurations.setAccessToken(configAccess_token);
var payment_data = {
transaction_amount: 100,
token: token,
description: 'Blue shirt',
installments: installments,
payment_method_id: payment_method_id,
issuer_id: issuer_id,
payer: {
email: 'john#yourdomain.com'
}
};
// Save and process the payment:
mercadopago.payment.save(payment_data).then((data) => {
Console.log(data.status);
}).catch( (error) => {
console.error(error)
});
};
I receive the payment info and I'm able to process the payment, however, the page keeps waiting for a promise-like response (stays loading indefinitely) after making the POST request. How could I handle this promise/response if I'm not explicitly making the POST request? I don't have access to the code that makes the POST request as it comes from the payment gateway itself.
I tried returning a response from my API endpoint with some data like this...
res.statusCode = 200;
res.setHeader('Content-Type', 'application/json');
res.json({success: 'success!'});
... but it just renders the JSON data as plain text after redirecting me to my API URL: "http://localhost:3000/api/checkout".
The API documentation doesn't offer any info about this matter as far as I know after hours researching it.
My goal is to display some kind of notification of success (like a toast for example) or find any other way of letting the user know the transaction was completed without creating a generic '/success' page that anyone could visit at any time.
I have little experience in backend development so any help to put me in the right direction to handle this promise/response would be highly appreciated.

React JS : CCAvenue Payment Integration

I want to integrate CC Avenue Payment gateway in my React JS Application.
When I click on Payment button, it should open CC Avenue payment window to make payment and after successful of payment , I want to get its response and redirect to thankyou page.
Below is the code i have tried.
I have installed Node CCAvenue plugin.
const nodeCCAvenue = require('node-ccavenue');
const ccav = new nodeCCAvenue.Configure({
merchant_id: XXXXXXX,
working_key: XXXXXXXXXXXXXX,
});
const orderParams = {
order_id: 123456,
currency: 'INR',
amount: '100',
redirect_url: encodeURIComponent(`URL`),
billing_name: 'John Doe',
// etc etc
};
const encryptedOrderData = ccav.getEncryptedOrder(orderParams);
what URL should I put in redirect_url so that it can open Payment window.
Any help would be great.
Thank You.
I'm the author of the node-ccavenue module so I think can answer this.
Don't use the node-ccavenue package on your client side with React. The module uses Node.js' crypto library to encode and decode order information. Additionally, you cannot expose your merchant_id or working_key by putting them in clientside scripts.
Use this in your backend code if your backend is written with Node.js and return the encryptedOrderData to the frontend via an api endpoint

Paypal subscription confusion

I've been working on a project for over 2 years and I am finally ready to launch, but first I have to integrate a subscription based payment option so I can actually make some money off of this thing. I've been trying to integrate paypal subscriptions for like 2 months now and it's a major hold up. Also, this is causing me to go bald. Please help!
I think it would be really helpful to have a kind of overview explanation describing the definate process that I need to follow in order to accept subscription based payments. The level of detail would include where each of the steps should occure; frontend or backend (server), and any intermediate steps necessary to understand what data is flowing where. Second to that, the actual code for the smart button with some comments indicating what part of the process the code is addressing. Maybe that's a lot to ask, but it would be greatly appreciated and I believe a great resource for others looking to do the same as I am currently.
At the moment, my primary issue is that when I set the URL pointing to the paypal SDK in my script take to include &intent=authorize, I am told in the error message that I need to set intent=capture, but when I set intent=capture I'm told I need to set intent=authorize. So now I'm confused as to what I am supposed to do; authorize the transaction or capture the transaction. I've been provided links to 2 different guides on the paypal developer website from paypal technical support which seem to contradict each other - the first link said nothing about capture or authorizing payments, the 2nd link does. But I don't understand the context on the second link. The first link is all client side, the second link is on client side and server side. Why would these intent=ca[ture/authorize be needed? I thought that once someone agrees to and completes signing up for a subscription, and I've captured their subscription id, that I don't need to do anything else in order to receive funds on the monthly basis setup in my plan, I would only have to query the paypal APIs to find out if they've paid up upon the customer signing in to my service.
I have setup a sandbox account and I've created a product and a plan. I've got the smart button rendering with my plan ID after the customer logs in.
If I set intent=capture in the paypal SDK script URL, the paypal window opens, you select payment and agree, and then I get this error in my console:
env: "sandbox"
err: "Error: Use intent=authorize to use client-side authorize"
referer: "localhost:88"
timestamp: "1589939180937"
uid: "fad5852fa3_mde6ndq6mdu"
But if I set intent=authorize, I click the smart button, the paypal window shows up and disappears quickly and then I get this error:
buttonSessionID: "e3bf3c6c3d_mdi6mdi6mzq"
env: "sandbox"
err: "Uncaught Error: Expected intent from order api call to be authorize, got capture. Please ensure you are passing intent=capture to the sdk url"
referer: "www.sandbox.paypal.com"
sessionID: "fad5852fa3_mde6ndq6mdu"
timestamp: "1589940160835"
Here is my code:
<!DOCTYPE html>
<head>
<!-- Add meta tags for mobile and IE -->
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
</head>
<body>
<!-- Set up a container element for the button -->
<div id="paypal-button-container"></div>
<!-- Include the PayPal JavaScript SDK -->
<script
src="https://www.paypal.com/sdk/js?client-id=CLIENT-ID-HERE&currency=USD&vault=true&intent=capture"></script>
<script>
let planid = 'P-48A5110983270751ML2P5NVI';
// Render the PayPal button into #paypal-button-container
paypal.Buttons({
// Set up the transaction
createSubscription: function (data, actions) {
// Create Subscription
return actions.subscription.create({ "plan_id": planid });
},
onApprove: function (data, actions) {
// Authorize the transaction
actions.order.authorize().then(function (authorization) {
// Get the authorization id
var authorizationID = authorization.purchase_units[0]
.payments.authorizations[0].id
// Call your server to validate and capture the transaction
return fetch('/api/company/paypal-transaction-complete', {
method: 'post',
headers: {
'content-type': 'application/json'
},
body: JSON.stringify({
orderID: data.orderID,
authorizationID: authorizationID,
data: data,
authorization: authorization
})
});
});
}
// Finalize the transaction? Which one do I want, to authorize or to finalize??
// onApprove: function (data, actions) {
// let result = actions.subscription.get();
// return actions.order.capture().then(function(details) {
// // Do I need to send something to my server here?
// // Show a success message to the buyer
// alert('Transaction completed by ' + details.payer.name.given_name + '!');
// });
// }
}).render('#paypal-button-container');
</script>
</body>
Thanks in advance for your help. This has been a most frustrating project.
Why are you using intent=authorize / intent=capture in the URL with subscriptions?
Why are you using actions.order.authorize() with subscriptions?
Who told you to do either of these things with subscriptions?
Please see the Subscriptions Integration guide, which does not include any mention of those things.

Braintree in Sandbox with Javascript SDK tokenizeCard return "Unable to tokenize card."

I am using Nodejs + javascript SDK, in which I am creating a new customer using predefined customer ID, which is working fine.
Now, using the same customer Id, I am generating a token at the backend and send it to the client. Now at client I am running .
var card = {
number: '4111111111111111',
cvv: '832',
expirationMonth: '10',
expirationYear: '2020',
cardholderName: 'Ankur Agarwal',
billingAddress: {
postalCode: '560076'
},
};
var client = new braintree.api.Client({clientToken: clientToken});
client.tokenizeCard(card, function (err, nonce) {
// Got Error "Unable to tokenize card"
})
Here is the http response it originally got from the server.
/**/callback_json1({"error":{"message":"User does not have the required permissions for this action"},"fieldErrors":[],"status":403})
I have enabled the API access for the account in the sandbox
There are some extra parameters which are not in docs, due to which its givng such a response. Once I removed the extra parameters from the request, its working fine.
I encountered similar error and it was caused by invalid client token. I was passing MerchantId instead of MerchantAccountId as a parameter.
Gateway.ClientToken.generate(new ClientTokenRequest()
{
MerchantAccountId = "Your MerchantAccountId" // NOT MerchantId
});
To manage your merchant accounts login to your Braintree control panel, go to Settings -> Processing and scroll down to Merchant Accounts

Categories

Resources