使用 omnipay paypal 处理 paypal redirect failuers
Handle paypal redirect failuers with omnipay paypal
我已经在我的 Laravel 网站上安装了 Omnipay paypal。
首先,我对 paypal 进行授权调用,如下所示:
$invoice = $this->find($id);
$gateway = Omnipay::create('PayPal_Express');
$gateway->setUsername(config('payment.paypal_api_username'));
$gateway->setPassword(config('payment.paypal_api_password'));
$gateway->setSignature(config('payment.paypal_signature'));
$gateway->setTestMode(config('payment.paypal_testmode'));
$response = $gateway->purchase([
'cancelUrl' => route('paypal.cancel'),
'returnUrl' => route('paypal.return'),
'amount' => $invoice->price.'.00',
'currency' => $invoice->currency->abbr,
'Description' => 'Sandbox test transaction'
])->send();
if($response->isRedirect()) {
// Redirect user to paypal login page
return $response->redirect();
} else {
Flash::error('Unable to authenticate against PayPal');
}
在此之后,用户将被重定向到 paypal 站点进行支付,如果成功,则将被重定向回 returnUrl。发生这种情况的地方:
$payment = Payment::where('paypal_token', '=', $token)->first();
$invoice = $payment->invoice;
$gateway = Omnipay::create('PayPal_Express');
$gateway->setUsername(config('payment.paypal_api_username'));
$gateway->setPassword(config('payment.paypal_api_password'));
$gateway->setSignature(config('payment.paypal_signature'));
$gateway->setTestMode(config('payment.paypal_testmode'));
$response = $gateway->completePurchase(array (
'cancelUrl' => route('paypal.cancel'),
'returnUrl' => route('paypal.success'),
'amount' => $invoice->price.'.00',
'currency' => $invoice->currency->abbr
))->send();
if($response->isSuccessful()) {
Event::fire(new MakePaymentEvent($invoice));
Flash::message('Thank you for your payment!');
} else {
Flash::error('Unable to complete transaction. Check your balance');
}
然而,从 paypal 重定向回时偶尔会出现一些失败,可能是浏览器关闭或网络故障导致用户无法重定向回我的 laravel 站点。
所以我尝试创建一个 cron 作业(laravel 中的调度程序)每 5 分钟检查一次未完成的付款,并尝试检查付款是否已成功转移并设置发票支付状态:
$gateway = Omnipay::create('PayPal_Rest');
$gateway->initialize(array (
'clientId' => config('payment.paypal_client_id'),
'secret' => config('payment.paypal_secret_id'),
'testMode' => config('payment.paypal_testmode'),
));
$transaction = $gateway->fetchPurchase();
$transaction->setTransactionReference($token);
$response = $transaction->send();
$data = $response->getData();
dd($data);
但我只从 paypal 收到此回复 api
array:4 [
"name" => "INVALID_RESOURCE_ID"
"message" => "The requested resource ID was not found"
"information_link" => "https://developer.paypal.com/webapps/developer/docs/api/#INVALID_RESOURCE_ID"
"debug_id" => "8240e7d79fa91"
]
那么我应该如何从用户重定向之前发出的授权请求中获取付款交易:
#data: array:6 [▼
"TOKEN" => "EC-9XF92859YM415352K"
"TIMESTAMP" => "2016-02-12T14:25:09Z"
"CORRELATIONID" => "e6a70075ad9d5"
"ACK" => "Success"
"VERSION" => "119.0"
"BUILD" => "18308778"
]
我已尝试使用令牌和 correlationid 获取交易,但其中 none 是有效的资源 ID
- 我建议您从 PayPal Express API 切换到 Paypal
休息 API。 REST API 更新、文档更好、更多
完成。
- 我建议您为每个人提供唯一的 return 并取消 URL
交易。这样做的一个例子是在 omnipay-paypal
REST API 的文档块。基本上你需要存储
调用 purchase() 之前的交易数据和交易 ID 以及
使用该 ID 作为 returnUrl 的一部分。然后代码在returnUrl
将知道这是针对哪个交易。
- 您创建一个 cron 作业来搜索丢失的交易的方法是正确的(我自己就是这样做的,除了我每天只做一次),但是您需要搜索由初始 purchase() 调用,而不是 returnUrl.
中提供的调用
因此,例如,查看您的初始代码,我添加了一些关于我将要进行的更改的评论:
// OK I'm assuming that your $id is a transaction ID, so we will use that.
$invoice = $this->find($id);
// Make the purchase call
$response = $gateway->purchase([
// Add $id to these two URLs.
'cancelUrl' => route('paypal.cancel') . '/' . $id,
'returnUrl' => route('paypal.return') . '/' . $id,
'amount' => $invoice->price.'.00',
'currency' => $invoice->currency->abbr,
'Description' => 'Sandbox test transaction'
])->send();
if($response->isRedirect()) {
// Get the transaction reference.
$txnRef = $response->getTransactionReference();
// Store the above $txnRef in the transaction somewhere.
// This will be the transaction reference you need to search for.
// Redirect user to paypal login page
return $response->redirect();
注意:
- $txnRef 是关键。
- 有些交易您有 $txnRef 但在 PayPal 上找不到。看起来这些是已取消的交易,它们会在一段时间后超时。如果找不到,则假设它们被取消。
- 在来自 PayPal fetchTransaction() 调用的响应数据中,将有一些交易返回不同的交易参考。这通常意味着交易已在 PayPal 端完成,您需要更新交易参考。
有关示例,请参阅 omnipay-paypal RestFetchTransactionRequest、RestFetchPurchaseRequest 和 RestListPurchaseRequest 类 中的文档。
我已经在我的 Laravel 网站上安装了 Omnipay paypal。 首先,我对 paypal 进行授权调用,如下所示:
$invoice = $this->find($id);
$gateway = Omnipay::create('PayPal_Express');
$gateway->setUsername(config('payment.paypal_api_username'));
$gateway->setPassword(config('payment.paypal_api_password'));
$gateway->setSignature(config('payment.paypal_signature'));
$gateway->setTestMode(config('payment.paypal_testmode'));
$response = $gateway->purchase([
'cancelUrl' => route('paypal.cancel'),
'returnUrl' => route('paypal.return'),
'amount' => $invoice->price.'.00',
'currency' => $invoice->currency->abbr,
'Description' => 'Sandbox test transaction'
])->send();
if($response->isRedirect()) {
// Redirect user to paypal login page
return $response->redirect();
} else {
Flash::error('Unable to authenticate against PayPal');
}
在此之后,用户将被重定向到 paypal 站点进行支付,如果成功,则将被重定向回 returnUrl。发生这种情况的地方:
$payment = Payment::where('paypal_token', '=', $token)->first();
$invoice = $payment->invoice;
$gateway = Omnipay::create('PayPal_Express');
$gateway->setUsername(config('payment.paypal_api_username'));
$gateway->setPassword(config('payment.paypal_api_password'));
$gateway->setSignature(config('payment.paypal_signature'));
$gateway->setTestMode(config('payment.paypal_testmode'));
$response = $gateway->completePurchase(array (
'cancelUrl' => route('paypal.cancel'),
'returnUrl' => route('paypal.success'),
'amount' => $invoice->price.'.00',
'currency' => $invoice->currency->abbr
))->send();
if($response->isSuccessful()) {
Event::fire(new MakePaymentEvent($invoice));
Flash::message('Thank you for your payment!');
} else {
Flash::error('Unable to complete transaction. Check your balance');
}
然而,从 paypal 重定向回时偶尔会出现一些失败,可能是浏览器关闭或网络故障导致用户无法重定向回我的 laravel 站点。
所以我尝试创建一个 cron 作业(laravel 中的调度程序)每 5 分钟检查一次未完成的付款,并尝试检查付款是否已成功转移并设置发票支付状态:
$gateway = Omnipay::create('PayPal_Rest');
$gateway->initialize(array (
'clientId' => config('payment.paypal_client_id'),
'secret' => config('payment.paypal_secret_id'),
'testMode' => config('payment.paypal_testmode'),
));
$transaction = $gateway->fetchPurchase();
$transaction->setTransactionReference($token);
$response = $transaction->send();
$data = $response->getData();
dd($data);
但我只从 paypal 收到此回复 api
array:4 [
"name" => "INVALID_RESOURCE_ID"
"message" => "The requested resource ID was not found"
"information_link" => "https://developer.paypal.com/webapps/developer/docs/api/#INVALID_RESOURCE_ID"
"debug_id" => "8240e7d79fa91"
]
那么我应该如何从用户重定向之前发出的授权请求中获取付款交易:
#data: array:6 [▼
"TOKEN" => "EC-9XF92859YM415352K"
"TIMESTAMP" => "2016-02-12T14:25:09Z"
"CORRELATIONID" => "e6a70075ad9d5"
"ACK" => "Success"
"VERSION" => "119.0"
"BUILD" => "18308778"
]
我已尝试使用令牌和 correlationid 获取交易,但其中 none 是有效的资源 ID
- 我建议您从 PayPal Express API 切换到 Paypal 休息 API。 REST API 更新、文档更好、更多 完成。
- 我建议您为每个人提供唯一的 return 并取消 URL 交易。这样做的一个例子是在 omnipay-paypal REST API 的文档块。基本上你需要存储 调用 purchase() 之前的交易数据和交易 ID 以及 使用该 ID 作为 returnUrl 的一部分。然后代码在returnUrl 将知道这是针对哪个交易。
- 您创建一个 cron 作业来搜索丢失的交易的方法是正确的(我自己就是这样做的,除了我每天只做一次),但是您需要搜索由初始 purchase() 调用,而不是 returnUrl. 中提供的调用
因此,例如,查看您的初始代码,我添加了一些关于我将要进行的更改的评论:
// OK I'm assuming that your $id is a transaction ID, so we will use that. $invoice = $this->find($id); // Make the purchase call $response = $gateway->purchase([ // Add $id to these two URLs. 'cancelUrl' => route('paypal.cancel') . '/' . $id, 'returnUrl' => route('paypal.return') . '/' . $id, 'amount' => $invoice->price.'.00', 'currency' => $invoice->currency->abbr, 'Description' => 'Sandbox test transaction' ])->send(); if($response->isRedirect()) { // Get the transaction reference. $txnRef = $response->getTransactionReference(); // Store the above $txnRef in the transaction somewhere. // This will be the transaction reference you need to search for. // Redirect user to paypal login page return $response->redirect();
注意:
- $txnRef 是关键。
- 有些交易您有 $txnRef 但在 PayPal 上找不到。看起来这些是已取消的交易,它们会在一段时间后超时。如果找不到,则假设它们被取消。
- 在来自 PayPal fetchTransaction() 调用的响应数据中,将有一些交易返回不同的交易参考。这通常意味着交易已在 PayPal 端完成,您需要更新交易参考。
有关示例,请参阅 omnipay-paypal RestFetchTransactionRequest、RestFetchPurchaseRequest 和 RestListPurchaseRequest 类 中的文档。