The response i keep getting at dd($finalResponse);
is:
RestResponse {#298 ▼
#statusCode: 400
#request: RestCompletePurchaseRequest {#300 ▶}
#data: array:4 [▼
"name" => "PAYMENT_NOT_APPROVED_FOR_EXECUTION"
"message" => "Payer has not approved payment"
"information_link" => "https://developer.paypal.com/webapps/developer/docs/api/#PAYMENT_NOT_APPROVED_FOR_EXECUTION"
"debug_id" => "5471589613718"
]
}
Here is the code.
$gateway = Omnipay::create('PayPal_Rest');
// Initialise the gateway
$gateway->initialize(array(
'clientId' => env('PAYMENT_SANDBOX_PAYPAL_CLIENTID'),
'secret' => env('PAYMENT_SANDBOX_PAYPAL_SECRET'),
'testMode' => true, // Or false when you are ready for live transactions
));
// Do an authorisation transaction on the gateway
$transaction = $gateway->authorize(array(
'returnUrl'=> env('PAYMENT_SANDBOX_PAYPAL_URL'),
'cancelUrl' => 'http://localhost:8000/cancel',
'amount' => '10.00',
'currency' => 'AUD',
'description' => 'This is a test authorize transaction.',
// 'card' => $card,
));
$response = $transaction->send();
if ($response->isSuccessful()) {
// Find the authorization ID
$authResponse = $response->getTransactionReference();
echo "Authorize transaction was successful!\n".$authResponse;
}else{
echo "Failed to auth transaction";
dd($response);
}
// Once the transaction has been approved, we need to complete it.
$transaction = $gateway->completePurchase(array(
'payerId' => $request->PayerID,
'transactionReference' => $authResponse
));
$finalResponse = $transaction->send();
dd($finalResponse);
if ($finalResponse->getData()) {
echo "Transaction was successful!\n";
// Find the authorization ID
$results = $finalResponse->getTransactionReference();
dd($results);
}else{
dd($finalResponse->getData());
}
After logging in as the payer and completing purchase, what else does the payer need to approve and how?
No, you aren't understanding the PayPal payment flow correctly. Here is the correct flow:
You do the call to Omnipay::create(), $gateway->initialize() and $gateway->authorize() just like you have them above. However for returnUrl you have to provide a URL on your site, just like you have for cancelUrl. Perhaps you mean to use http://localhost:8000/return (although better would be to have a transaction ID or something in the return URL).
The response from the $gateway->authorize() will be of type RedirectResponse. You can check this:
// Do an authorisation transaction on the gateway
$transaction = $gateway->authorize(array(
'returnUrl'=> env('PAYMENT_SANDBOX_PAYPAL_URL'),
'cancelUrl' => 'http://localhost:8000/cancel',
'amount' => '10.00',
'currency' => 'AUD',
'description' => 'This is a test authorize transaction.',
// 'card' => $card,
));
$response = $transaction->send();
if ($response->isRedirect()) {
// Yes it's a redirect. Redirect the customer to this URL:
$redirectUrl = $response->getRedirectUrl();
}
At that point the initial handshake with the customer is over. You have now redirected the customer to the PayPal web site where they will authorize the transaction by logging in with their PayPal account email address and password, check the invoice, click the button that says that they agree to pay.
The next thing that happens is that the customer is redirected by PayPal back to your web site, on the redirectUrl that you provided in the authorize() call. That will jump to a different place in your code. At that point you call completeAuthorize, just like you had in your code earlier:
// Once the transaction has been approved, we need to complete it.
$transaction = $gateway->completePurchase(array(
'payerId' => $request->PayerID,
'transactionReference' => $authResponse
));
$finalResponse = $transaction->send();
dd($finalResponse);
if ($finalResponse->getData()) {
echo "Transaction was successful!\n";
// Find the authorization ID
$results = $finalResponse->getTransactionReference();
dd($results);
}else{
dd($finalResponse->getData());
}
Note that you need to have stored the Payer ID and transactionReference from the authorize call and be able to recover those in your returnUrl code.
You also need to be able to handle the cancelUrl case, where the customer has decided not to agree to the payment on PayPal and gets sent back to the cancelUrl URL on your website instead.
Finally you need to be able to handle the occasional cases where the customer completes the payment on the PayPal web site but does not end back on your returnUrl. This could be because of a network issue, the browser crashed, or because the customer closed their browser between clicking "Agree to Pay" on PayPal and landing back on your site. The best way to handle those is with the omnipay-paypal calls fetchPurchase() or listPurchase().
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With