Как интегрировать платежный шлюз в yii2 с использованием расширения PayPal для Yii2
Как использовать расширение PayPal в yii2. Я использую эту ссылку
https://github.com/marciocamello/yii2-paypal.
Я установил расширение, а также добавил код в файле конфигурации.
Но больше информации о том, что делать дальше. Поэтому, пожалуйста, помогите мне.
Спасибо
Ответы
Ответ 1
Нет необходимости использовать расширение для этого. Вы можете просто установить пакет paypal/rest-api-sdk-php и выполнить следующие шаги.
1. Создайте компонент, чтобы склеить Paypal на Yii2
Создайте папку components
в каталоге @app
. Если вы используете базовый шаблон, это та же самая папка, что и 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 API context
// override Yii 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
В Сделайте свой первый вызов API в Yii2,
Откройте действие контроллера, в котором вы хотите обрабатывать платежи, и включите следующее
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.
Как только вы подключитесь, вы сможете выполнять другие задачи.
Ответ 2
Это мое решение, оно работает с расширенным tempalte yii2!
Я переместил этот класс marciocamello/yii2-paypal/PayPal.php из папки поставщика в общий/компонент/PayPal.php
Вы должны "включить" common\components\paypal в frontend\config\main.php в разделе компонентов:
'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,
]
],
],
В PPHttpConfig.php в строке 11 я изменил следующую строку
//CURLOPT_SSLVERSION => 3,
CURLOPT_SSLVERSION => 'CURL_SSLVERSION_TLSv1',
В PPLoggingManager.php в строке 48-52 i'v жестко закодирован путь журнала
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;
}
В контроллере сайта i'v называется функция компонента
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, вы можете распечатать весь ответ PayPal с сообщениями об ошибках и т.д. в PPHttpConnection.php в строке 107.
$ex->setData($result);
// echo '<pre>';
// print_r($ex);exit;
throw $ex;
Ответ 3
https://github.com/marciocamello/yii2-paypal. С помощью этого расширения вы можете просто установить/установить библиотеку paypal, которая доступна на этой ссылке,
https://github.com/paypal/PayPal-PHP-SDK
Этот papypal-php-SDK имеет примеры с различными методами.
Я установил/установил эту библиотеку в YII2 и использовал способы оплаты.
Ответ 4
Я использую paypal express checkout, основанный на Rest API на моем веб-сайте. Нет необходимости в расширении сторонних производителей. Решение может быть применено к любому веб-сайту в целом, не ограничиваясь рамками Yii. Чтобы получить базовые понятия, прочитайте https://developer.paypal.com/docs/integration/direct/express-checkout/integration-jsv4/
Вот мой подход:
-
Создайте APE REST API в https://developer.paypal.com. После создания вашего APP вы получите идентификатор клиента и секретный ключ, который будет использоваться позже для аутентификации.
-
На веб-странице, где вы хотите отобразить кнопку выписки, создайте пустой div
<div id="paypal-button"></div>
-
Включите https://www.paypalobjects.com/api/checkout.js javascript в свой актив.
4.Нажмите кнопку paypal со следующим кодом Javascript
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;
}
}