如何使用 Yii2 的 PayPal 扩展在 yii2 中集成支付网关
Posted
技术标签:
【中文标题】如何使用 Yii2 的 PayPal 扩展在 yii2 中集成支付网关【英文标题】:How to integrate payment gateway in yii2 using PayPal extension for the Yii2 【发布时间】:2015-04-05 06:45:50 【问题描述】:如何在yii2中使用paypal扩展。我正在使用此链接 https://github.com/marciocamello/yii2-paypal。 我安装了扩展并在配置文件中添加了代码。
但没有更多信息下一步该做什么。所以请帮助我。
谢谢
【问题讨论】:
也许最好询问实际的开发人员。您可以在 Github 上创建有关文档问题的问题。据我所知,文档很差,没有其他链接可以。另一种选择是自己查看源代码来弄清楚。主类(除了 init 和 demo)和配置文件中只有一种方法。也许扩展正处于开发的初始阶段。 不是答案,但想知道paypal.github.io/PayPal-php-SDK 是否有帮助。我不是 YII 开发人员,因此不确定是否需要任何特殊考虑。 PayPal-PHP-SDK 在作曲家中可用paypal/rest-api-sdk-php
。
【参考方案1】:
我在我的网站中使用基于 Rest API 的 paypal express checkout。无需任何第三方扩展。该解决方案一般适用于任何网站,不限于 Yii 框架。要了解基本概念,请阅读https://developer.paypal.com/docs/integration/direct/express-checkout/integration-jsv4/
这是我的方法:
在 https://developer.paypal.com 中创建一个 REST API 应用程序。一旦你创建了你的APP,你就会得到Client ID和Secret Key,供以后进行身份验证使用。
在您要显示结帐按钮的网页上,创建一个空 div
<div id="paypal-button"></div>
在您的资产中包含 https://www.paypalobjects.com/api/checkout.js javascript。
4.使用以下Javascript代码渲染paypal按钮
paypal.Button.render(
env: 'sandbox', // Specify 'sandbox' for the test environment
client:
sandbox: 'CLIENT-ID of your APP in step1'
,
payment: function (resolve, reject)
/* URL which would create payment */
var CREATE_PAYMENT_URL = '/transactions/create-paypal';
paypal.request.post(CREATE_PAYMENT_URL)
.then(function (data)
resolve(data.paymentID);
)
.catch(function (err)
reject(err);
);
,
onAuthorize: function (data, actions)
// Execute the payment here, when the buyer authorize and approves the transaction
var EXECUTE_PAYMENT_URL = '/transactions/execute-paypal';
paypal.request.post(EXECUTE_PAYMENT_URL,
paymentID: data.paymentID, payerID: data.payerID, token: data.paymentToken,serviceId:serviceId)
.then(function (data)
console.log(data);
if(data.http_code == '200')
/* payment done .. do something here */
handleCreateService(url);
else
/* something didn't went right with payment */
)
.catch(function (err)
/* catch any exceptions */
console.log(err);
);
, '#paypal-button');
现在您需要在控制器中编写创建付款并执行付款方式的代码。
/* Create Paypal function will pass token,
paymentID back to JS in step 4. */
public function actionCreatePaypal()
$paypal = new Paypal();
$paypal->getToken();
$res = $paypal->createPayment();
echo json_encode($res);
public function actionExecutePaypal()
$paymentID = $_POST['paymentID'];
$payerID = $_POST['payerID'];
$access_token = $_POST['token'];
$paypal = new Paypal(['paymentID'=>$paymentID,'payerID' =>$payerID,'access_token' =>$access_token]);
$paypal->getToken();
$res = $paypal->executePayment();
echo json_encode($res);
最后创建一个组件来进行身份验证/生成令牌并执行支付。
class Paypal
public $url;
public $env;
public $clientId;
public $clientSecret;
public $access_token;
public $paymentID;
public $payerID;
public $premiumService;
public function __construct($params=0)
$this->access_token = '';
/* for sandbox url is https://api.sandbox.paypal.com */
$this->url = \Yii::$app->params['paypal_url'];
$this->clientId = \Yii::$app->params['paypal_clientId'];
$this->clientSecret = \Yii::$app->params['paypal_clientSecret'];
if(isset($params['paymentID']))
$this->paymentID = $params['paymentID'];
if(isset($params['payerID']))
$this->payerID = $params['payerID'];
if(isset($params['access_token']))
$this->access_token = $params['access_token'];
/* This is where you describe the product you are selling */
$this->premiumService = '
"intent":"sale",
"redirect_urls":
"cancel_url":"https://cancelurl.com",
"return_url":"https://returnurl.com"
,
"payer":
"payment_method":"paypal"
,
"transactions":[
"amount":
"currency":"USD",
"total":"39.00"
,
"item_list":
"items": [
"quantity": "1",
"name": "Premium Service",
"price": "39.00",
"currency": "USD",
"description": "Purchase allows one time use of this premium service"
]
,
"description":"Premium Service"
]
';
public function getToken()
$curlUrl = $this->url."/v1/oauth2/token";
$curlHeader = array(
"Content-type" => "application/json",
"Authorization: Basic ". base64_encode( $this->clientId .":". $this->clientSecret),
);
$postData = array(
"grant_type" => "client_credentials"
);
$curlPostData = http_build_query($postData);
$curlResponse = $this->curlCall($curlUrl, $curlHeader, $curlPostData);
if($curlResponse['http_code'] == 200)
$this->access_token = $curlResponse['json']['access_token'];
public function createPayment()
$curlUrl = $this->url."/v1/payments/payment";
$curlHeader = array(
"Content-Type:application/json",
"Authorization:Bearer ". $this->access_token,
);
$curlResponse = $this->curlCall($curlUrl, $curlHeader, $this->premiumService);
$id = null;
$approval_url = null;
if($curlResponse['http_code'] == 201)
$id = $curlResponse['json']['id'];
foreach ($curlResponse['json']['links'] as $link)
if($link['rel'] == 'approval_url')
$approval_url = $link['href'];
$res = ['paymentID' =>$id,'approval_url'=>$approval_url];
return $res;
public function executePayment()
$curlUrl = $this->url."/v1/payments/payment/".$this->paymentID."/execute";
$curlHeader = array(
"Content-Type:application/json",
"Authorization:Bearer ".$this->access_token,
);
$postData = array(
"payer_id" => $this->payerID
);
$curlPostData = json_encode($postData);
$curlResponse = $this->curlCall($curlUrl, $curlHeader, $curlPostData);
return $curlResponse;
function curlCall($curlServiceUrl, $curlHeader, $curlPostData)
// response container
$resp = array(
"http_code" => 0,
"json" => ""
);
//set the cURL parameters
$ch = curl_init($curlServiceUrl);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
//turning off the server and peer verification(TrustManager Concept).
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_SSLVERSION , 'CURL_SSLVERSION_TLSv1_2');
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
//curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $curlHeader);
if(!is_null($curlPostData))
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $curlPostData);
//getting response from server
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch); // close cURL handler
// some kind of an error happened
if (empty($response))
return $resp;
$resp["http_code"] = $http_code;
$resp["json"] = json_decode($response, true);
return $resp;
【讨论】:
【参考方案2】:无需为此使用扩展程序。您可以简单地安装paypal/rest-api-sdk-php 包并执行以下步骤。
1。创建一个组件将 Paypal 粘合到 Yii2
在您的@app
目录中创建一个components
文件夹。如果您使用的是基本模板,则这是与webroot
相同的文件夹;在高级模板中,此文件夹位于您要启用付款的应用中。
创建一个PHP类文件(例如CashMoney
),内容如下
use yii\base\Component;
use PayPal\Rest\ApiContext;
use PayPal\Auth\OAuthTokenCredential;
class CashMoney extends Component
public $client_id;
public $client_secret;
private $apiContext; // paypal's API context
// override Yii's object init()
function init()
$this->apiContext = new ApiContext(
new OAuthTokenCredential($this->client_id, $this->client_secret)
);
public function getContext()
return $this->apiContext;
这足以开始。稍后您可以选择添加特定于 PayPal 的其他配置。
2。用 Yii2 注册你的胶水组件
在您的app/config/main.php
(或app/config/main-local.php
)中,包含以下内容以注册CashMoney
组件。
'components' => [
...
'cm' => [ // bad abbreviation of "CashMoney"; not sustainable long-term
'class' => 'app/components/CashMoney', // note: this has to correspond with the newly created folder, else you'd get a ReflectionError
// Next up, we set the public parameters of the class
'client_id' => 'YOUR-CLIENT-ID-FROM-PAYPAL',
'client_secret' => 'YOUR-CLIENT-SECRET-FROM-PAYPAL',
// You may choose to include other configuration options from PayPal
// as they have specified in the documentation
],
...
]
现在我们的支付组件注册为CashMoney
,我们可以使用Yii::$app->cm
访问它。很酷吧?
3。进行 API 调用
致 Yii2 中的Make Your First API call,
打开您要在其中处理付款的控制器操作,并包括以下内容
use Yii;
...
use PayPal\Api\CreditCard;
use PayPal\Exception\PaypalConnectionException;
class PaymentsController // or whatever yours is called
...
public function actionMakePayments // or whatever yours is called
...
$card = new PayPalCreditCard;
$card->setType('visa')
->setNumber('4111111111111111')
->setExpireMonth('06')
->setExpireYear('2018')
->setCvv2('782')
->setFirstName('Richie')
->setLastName('Richardson');
try
$card->create(Yii::$app->cm->getContext());
// ...and for debugging purposes
echo '<pre>';
var_dump('Success scenario');
echo $card;
catch (PayPalConnectionException)
echo '<pre>';
var_dump('Failure scenario');
echo $e;
...
...
预期的输出类似于 PayPal 文档中的输出。
连接成功后,您应该能够执行其他任务。
【讨论】:
$this->apiContext = new ApiContext( new OAuthTokenCredential($this->client_id, $this->client_secret); );
应该是 $this->apiContext = new ApiContext( new OAuthTokenCredential($this->client_id, $this->client_secret) );
。 public function getContext() return $this->apiContext();
也应该是 public function getContext() return $this->apiContext;
。请纠正他们。由于最小字符限制而无法编辑(这很糟糕)。
你在哪里初始化CashMoney
组件?
您第一次调用时引用的链接与您添加的代码块没有任何相似之处,您可能需要更新代码,因为没有任何名为 PayPalCreditCard
的类【参考方案3】:
https://github.com/marciocamello/yii2-paypal。通过此扩展,您只需设置/安装可在此链接上使用的贝宝库- https://github.com/paypal/PayPal-PHP-SDK 这个 papypal-php-SDK 有不同方法的例子。
我已经在 YII2 中安装/设置了这个库并使用了支付方式。
【讨论】:
剧透:最低支持:PHP 5.5【参考方案4】:这是我的解决方案,它适用于 yii2 高级模板!
我已将此类 marciocamello/yii2-paypal/PayPal.php 从供应商文件夹移至 common/component/PayPal.php
您必须在组件部分下的 frontend\config\main.php 中“包含”common\components\paypal:
'components' => [
'paypal'=> [
'class' => 'common\components\Paypal',
'clientId' => 'your id you can find it over your paypal develpoer account. Ypu ah to create an application',
'clientSecret' => 'your id you can find it over your paypal develpoer account. Ypu ah to create an application',
'isProduction' => false,
// This is config file for the PayPal system
'config' => [
'http.ConnectionTimeOut' => 30,
'http.Retry' => 1,
'mode' => \common\components\Paypal::MODE_SANDBOX,
'log.LogEnabled' => YII_DEBUG ? 1 : 0,
'log.FileName' => '@runtime/logs/paypal.log',
'log.LogLevel' => \common\components\Paypal::LOG_LEVEL_INFO,
]
],
],
在第 11 行的 PPHttpConfig.php 中,我更改了以下行
//CURLOPT_SSLVERSION => 3,
CURLOPT_SSLVERSION => 'CURL_SSLVERSION_TLSv1',
在第 48-52 行的 PPLoggingManager.php 中,我对日志路径进行了硬编码
if($this->isLoggingEnabled)
$this->loggerFile = $_SERVER['DOCUMENT_ROOT'].'/domain/frontend/runtime/logs/paypal.log';//($config['log.FileName']) ? $config['log.FileName'] : ini_get('error_log');
$loggingLevel = strtoupper($config['log.LogLevel']);
$this->loggingLevel = (isset($loggingLevel) && defined(__NAMESPACE__."\\PPLoggingLevel::$loggingLevel")) ? constant(__NAMESPACE__."\\PPLoggingLevel::$loggingLevel") : PPLoggingManager::DEFAULT_LOGGING_LEVEL;
在站点控制器中,我调用了组件函数
echo '<pre/>';
print_r(Yii::$app->paypal->payDemo());
exit();
我收到了带有重定向 url、transactionId 等的成功响应。
-------------- 400 ERROR Debuging ----------
我总是收到 400 错误,因为我的价格格式有问题,我使用 number_format 函数修复了它。
我稍微修改了 payDemo() 函数。
$amount = 16;
$formattedAmount = number_format($amount,2);
$payer = new Payer();
$payer->setPayment_method("paypal");
$item1 = new Item();
$item1->setName('Ground Coffee 40 oz')
->setCurrency('USD')
->setQuantity(1)
->setPrice($formattedAmount);
$item2 = new Item();
$item2->setName('Granola bars')
->setCurrency('USD')
->setQuantity(1)
->setPrice($formattedAmount);
$itemList = new ItemList();
$itemList->setItems(array($item1, $item2));
// $amountDetails = new Details();
// $amountDetails->setSubtotal('7');
// $amountDetails->setTax('0.00');
// $amountDetails->setShipping('0.00');
$amount = new Amount();
$amount->setCurrency('USD');
$amount->setTotal(number_format((2*$formattedAmount),2));
// $amount->setDetails($amountDetails);
$transaction = new Transaction();
$transaction->setDescription("creating a payment");
$transaction->setItemList($itemList);
$transaction->setAmount($amount);
//$baseUrl = getBaseUrl();
$redirectUrls = new RedirectUrls();
$redirectUrls->setReturn_url("https://devtools-paypal.com/guide/pay_paypal/php?success=true");
$redirectUrls->setCancel_url("https://devtools-paypal.com/guide/pay_paypal/php?cancel=true");
$payment = new Payment();
$payment->setIntent("sale");
$payment->setPayer($payer);
$payment->setRedirect_urls($redirectUrls);
$payment->setTransactions(array($transaction));
return $payment->create($this->_apiContext);
如果您仍然收到 400 或 40x 错误,您可以在第 107 行的 PPHttpConnection.php 中打印带有错误消息等的整个 PayPal 响应。
$ex->setData($result);
// echo '<pre>';
// print_r($ex);exit;
throw $ex;
【讨论】:
您好 user3387825 感谢您的回复,抱歉回复晚了。我按照你说的做了,但我得到了错误(“设置未知属性:common\components\Paypal::config”)请帮助我谢谢 您好,能否提供您的电子邮件地址,我有一个带有此 PayPal 模块的 YII2 高级入门项目,它运行良好。我可以通过电子邮件发送给你。 :) 我刚发了一封电子邮件:)。如果您有任何问题,请随时与我联系 感谢 user3387825 的关注,但我没有收到您的电子邮件。你能再发一次吗?我的电子邮件地址是 gam.jatin.vaghasiya@gmail.com 我正在等待您的回复。谢谢 请检查您的收件箱文件夹。我已经发送了一个链接,您可以在其中下载该项目。祝你有美好的一天。以上是关于如何使用 Yii2 的 PayPal 扩展在 yii2 中集成支付网关的主要内容,如果未能解决你的问题,请参考以下文章