PayPal Rest API Live and sandbox payment not captured - php

Developed PHP Paypal Integration via REST API.
when creating payment intent to get url to redirect user to Payment gateway it works fine.
I get the redirect url as well.
Example redirect url live mode
https://www.paypal.com/checkoutnow?token=7JR976187U6560045
But when we go to Payment page we can select either to logged in to Paypal account or pay as a guest using credit or debit card.
But for the logged in user it shows select the payment source (card) to pay but when we click on proceed or review it always not going to proceed to next step or to thank you page it reload back to same page without showing any error or warning.
This happens in Sandbox mode as well.
When we select pay via Credit card without logging in it it loads the card details entering page but after adding the cart it will not accept the payment and shows card was declined message. Cards has funds. Something happening in Sandbox with test card details.
below is sample code used for generate payment intent.
//first get the access token
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://api.paypal.com/v1/oauth2/token",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "grant_type=client_credentials",
CURLOPT_HTTPHEADER => array(
"Authorization: Basic " . base64_encode(PAYPAL_ID.":".PAYPAL_SECRET),
"Content-Type: application/x-www-form-urlencoded"
),
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
exit();
}
$responseData = json_decode($response);
$accessToken = $responseData->access_token;
$requestBody = [
'intent' => 'CAPTURE',
'purchase_units' => [[
'amount' => [
'currency_code' => 'EUR',
'value' => $send_total, //cart total
],
]],
'redirect_urls' => [
'return_url' => $thank_you_link,
'cancel_url' => $cart_link,
]
];
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.paypal.com/v2/checkout/orders",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode($requestBody),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"Authorization: Bearer $accessToken"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
exit();
}
$responseData = json_decode($response);
//var_dump($responseData);
if ($responseData->status !== 'CREATED') {
echo "Order creation failed: " . $responseData->debug_id;
exit();
}
$orderId = $responseData->id;
$_SESSION['paypal_id'] = $orderId;
$approveUrl = '';
foreach ($responseData->links as $link) {
if ($link->rel === 'approve') {
$approveUrl = $link->href;
break;
}
}
if (!$approveUrl) {
echo "Approve URL not found";
exit();
}
$data_back = array();
$data_back['url'] = $approveUrl;
Tried both live mode and sandbox mode.

You are missing the capture step.
When redirecting away from your site to PayPal (not recommended), the order you created must have a return_url so that the payer can be redirected back after approving the payment. Then you need to capture the payment with another API call.
Rather than redirecting away, the best user experience is to pair API order creation and capture with the JS SDK for the approval flow. This keeps your site loaded in the background at all times, and is documented here (the sample there uses Node.js for the backend, but you can of course implement it in any environment including PHP).
There will be no PayPal transaction until you capture the payment. After the capture API call you can then display a message of success or failure. The server route that does the capture API call should also verify the captured amount was correct in the API response before storing the result as a successful payment and doing anything automated with the result.

Related

PHP OAUTH2 "error":"invalid_grant","error_description":"The specified authorization code cannot be used by this client application."

I am working on setting up authorization in a php application with oauth2 and am struggling to get a access token back. I get the error {"error":"invalid_grant","error_description":"The specified authorization code cannot be used by this client application."}
I cannot find evidence of this error anywhere. I imagine this error may come from mismatched return urls but since mine come from the same variable I'm not sure how that could be.
Here is my code:
if(isset($_POST['code'])){
$access_token = getAccessToken($_POST["code"]);
$resource = getResource($access_token);
}else if(!isset($_POST['code'])){
header( "Location: https://growthzoneapp.com/oauth/authorize?client_id=$CLIENT_ID &response_type=code&response_mode=form_post&redirect_uri=$REDIRECT_URI&scope=openid+profile"
);
}
function getAccessToken($authorization_code) {
global $CLIENT_ID, $CLIENT_SECRET, $REDIRECT_URI;
$content = "grant_type=authorization_code&code=$authorization_code&client_id=$CLIENT_ID&client_secret=$CLIENT_SECRET&redirect_uri=$REDIRECT_URI";
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => 'https://growthzoneapp.com/oauth/token',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => $content ,
CURLOPT_HTTPHEADER => [
"content-type: application/x-www-form-urlencoded"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
}
This error occurs when the client ID in the authorization request doesn't match the client ID in the access token request. In this case there is an extra space added in the authorization request "$CLIENT_ID &":
header( "Location: https://growthzoneapp.com/oauth/authorize?client_id=$CLIENT_ID &response_type=code&response_mode=form_post&redirect_uri=$REDIRECT_URI&scope=openid+profile"

Status on paypal is still APPROVED

I have a problem with payment integrationwith PayPal.
I am using REST API and this my code for creating an order:
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://api.sandbox.paypal.com/v2/checkout/orders",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => '{
"intent": "CAPTURE",
"purchase_units": [
{
"reference_id": "PUHF",
"amount": {
"currency_code": "PLN",
"value": "100.00"
}
}
],
"application_context": {
"return_url": "http://www.mywebside.com",
"cancel_url": ""
}
}',
CURLOPT_HTTPHEADER => array(
'accept: application/json',
'accept-language: en_US',
'authorization: Bearer '.$access_token.'',
'content-type: application/json'
),
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
I work in a sandbox environment. I go to the payment page and transfer virtual money.
When it redirects me to my site, then I check the order status. Status has value = "APPROVED" not "COMPLETED" and money is also not credited to the account. What it depends on?
You need two API calls, one to 'Set Up Transaction' and create the order, followed by one to 'Capture Transaction' after the approval, as documented here:
https://developer.paypal.com/docs/checkout/reference/server-integration/
If you do not capture an order, it will stay in an approved state.
For the best user experience, do not use any redirects. At all. Keep your site loaded in the background, and present the user with a modern in-context login for the approval. Here is the UI for that: https://developer.paypal.com/demo/checkout/#/pattern/server

Unable to make the HTTP POST request with the AWS signature in drupal 8 / PHP

We are unable to make the HTTP POST request call to fetch the results and note that autherization type is AWS signature authorization.
In Drupal -8, we have tried with 'AWS connector' module but can not find the exact service for the HTTP POST request with the AWS signature authorization.
Notes:
I got some info on this at drupalize.me site.
<code>
$client = \Drupal::httpClient();
$request = $client->get('https://api.github.com/user', [
'auth' => ['username','password']
]);
$response = $request->getBody();
(Ref: https://drupalize.me/blog/201512/speak-http-drupal-httpclient)
</code>
The auth is for above is basic authentication. But I need for “AWS Signature”
We have tried the below curl code and not able to get the any result. Its showing the white blank screen without any errors.
<code>
$startTimestamp = time();
$amz = gmdate('Ymd\THis\Z', $startTimestamp);
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://api-runtime.us-east-1.amazonaws.com/endpoint",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "{\n\t\"campaignArn\":\"arn:aws:test:us-east-1:12456:campaign/test\",\n\t\"numResults\":2,\n\t\"userId\":\"400\"\n}",
CURLOPT_HTTPHEADER => array(
'"authorization: AWS4-HMAC-SHA256 Credential=**********/20191205/us-east-1/Test/aws4_request,
SignedHeaders=content-length;content-type;host;x-amz-date;x-amz-target,
Signature=' . $signature . '"',
'"cache-control: no-cache"',
'"content-type: application/json"',
'"host: test-runtime.us-east-1.amazonaws.com"',
'"x-amz-date:' . $amz . '"',
'"x-amz-target: getrecommendations"'
),
));
$result = curl_exec($curl);
if($result === false) {
echo "Error in cURL : " . curl_error($curl);
}
else {
echo 'no error'.$result;
}
Please check and share the valuable inputs / reference.

How to store the response generated from an api call to the mysql database in wordpress

I am new to understanding the coding languages and have started to learn things using wordpress.
I am trying to integrate a payment gateway and could generate the access_token and refresh_token which i need to store the same into my database for making further api calls for payments and user data updation.
The following is my code to run to generate tokens.
Please help as to how to store the token values in database.
I have tried replicating the wordpress register code to insert values, but
could not succeed.
<?php
session_start();
include_once "page-signup.php";
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://test.instamojo.com/oauth2/token/",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS =>
"client_id=gC4z8rBV55SDiavZobpvZCcanwK3mbnY
&client_secret=dYFbCXaX9WUy1c3kkCXV8JRJkTxmLcxCXwncVKWlWsh8c0QOI
5Uz30PCzOieC879RT7PLsEwrRKZDvZXqYpF5fZiE2Z62z3dly7p7ZUbGHTmOWmBsh3
&grant_type=password
&username=$username
&password=$password",
CURLOPT_HTTPHEADER => array(
"Cache-Control: no-cache",
"Content-Type: application/x-www-form-urlencoded",
),
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
$json_decode=json_decode($response,true);
$refresh_token=$json_decode['refresh_token'];
$access_token=$json_decode['access_token'];
}
echo $response;
?>
Probably the best way to store and retrieve this info from wordpress db is to use the Options API: with only one command you can store, retrieve and delete the token.
Normally the wordpress options uses a normalized array but you can also store directly a json token or simply a string.

How to return customer info from paypal?

I understand this can be done.
Here's what I've tried:
$request = curl_init();
// Set request options
curl_setopt_array($request, array
(
CURLOPT_URL => 'https://www.paypal.com/cgi-bin/webscr',
CURLOPT_POST => TRUE,
CURLOPT_POSTFIELDS => http_build_query(array
(
'cmd' => '_notify-synch',
'tx' => $tx,
'at' => "xxxxxxxxxxxxxxxxx",
)),
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_HEADER => FALSE,
// CURLOPT_SSL_VERIFYPEER => TRUE,
// CURLOPT_CAINFO => 'cacert.pem',
));
// Execute request and get response and status code
$response = curl_exec($request);
$status = curl_getinfo($request, CURLINFO_HTTP_CODE);
var_dump($response);
die();
// Close connection
curl_close($request);
When I send the curl request to https://www.paypal.com/cgi-bin/webscr, I recieve this error:
"FAIL Error: 4003"
When I send it to https://www.sandbox.paypal.com/cgi-bin/webscr, It returns nothing and a status of 0.
My account is sandbox at the moment. I've had this working but it doesn't work anymore.
Can someone please help.
Thanks
Usually, we return customer information only when Paypal calls back the ipn on your website.
You can use:
https://github.com/Quixotix/PHP-PayPal-IPN
For testing, you can use GET to redirect buyers to paypal, something like this:
# redirect to paypal
$redirect = 'https://www'.$addsand.'.paypal.com/cgi-bin/webscr?rm=2&cmd=_xclick&txn_type=express_checkout&no_note=1&no_shipping=1&return='.$return.'&cancel_return='.$cancel_return.'&notify_url='.$notify_url.'&image_url='.$image_url.'&business='.$paypaluser.'&currency_code='.$paypalcurrency.'&amount='.$price.'&mc_gross='.$price.'&item_name='.$product.'&item_number='.$planid.'&custom='.$uid; header("Location: $redirect"); exit();

Categories