причина
Некоторое время назад, поскольку в проекте необходимо реализовать функцию оплаты мобильного веб-сайта Alipay, я написал эту статью для протокола.
Бэкенд-фреймворк: Laravel 5.5
Бизнес-функции
Продавцам удобно интегрировать платежную функцию Alipay в мобильное веб-приложение. Продавец вызывает интерфейс веб-платежей, предоставленный Alipay на веб-странице, чтобы активировать платежный модуль в клиенте Alipay, веб-страница продавца переходит к Alipay для завершения платежа, а после завершения платежа возвращается к веб-страницу продавца и, наконец, отобразить результат платежа. Если клиент Alipay не может быть запущен, он автоматически войдет в процесс оплаты на веб-странице через определенный период времени.
1. Создайте приложение
Ссылка на сайт:Финансовая открытая платформа Alipay Ant
Уведомление:
- Требуется подтвержденная учетная запись Alipay с настоящим именем.
- Предприятия или отдельные промышленные и торговые домохозяйства могут подать заявку
- Требуется реальная и действующая бизнес-лицензия, а веб-сайт должен быть зарегистрирован через ICP.
Перейдите на открытую платформу Ant Financial -> Центр разработчиков -> Веб-приложение и мобильное приложение. Создавайте приложения по запросу, здесь я создаюВеб/мобильные приложения.
После того, как создание будет завершено, отправьте его для рассмотрения. Большинство приложений необходимо подписать до того, как они могут быть использованы, и договор требует бизнес-лицензии.
2. Настройте среду приложения
После завершения настройки ее можно отправить на проверку. После того, как разработчик нажмет «Отправить на проверку», проверка займет один рабочий день. После того, как приложение успешно переходит в онлайн, состояние становится онлайн, и приложение в этом состоянии может вызывать интерфейс производственной среды.
3. Конфигурация вызова интерфейса
В настоящее время существует множество платежных интерфейсов, интегрированных с alipay SDK в laravel. Обычно используются следующие:
OmniPay-laravel:ссылка на github OmniPay-laravel
latrell/alipay:ссылка на github latrell/alipay
...
Из-за нужд проекта здесь я использую родной пакет SDK от alipay.
Сначала загрузите демонстрационную версию PHP:Демо-версия PHP для мобильных платежей на веб-сайте Alipay
Из index.php видно, что демо поддерживает следующие функции
手机网站2.0支付(接口名:alipay.trade.wap.pay)
手机网站2.0订单查询 (接口名:alipay.trade.query)
手机网站2.0订单退款 (接口名:alipay.trade.refund)
手机网站2.0订单退款查询(接口名:alipay.trade.fastpay.refund.query)
手机网站2.0账单下载(接口名:alipay.data.dataservice.bill.downloadurl.query)
Где config.php — файл конфигурации:
<?php
$config = array (
//应用ID,您的APPID。
'app_id' => "",
//商户私钥,您的原始格式RSA私钥
'merchant_private_key' => "",
//异步通知地址
'notify_url' => "",
//http://工程公网访问地址/alipay.trade.wap.pay-PHP-UTF-8/notify_url.php
//同步跳转
'return_url' => "",
//http://mitsein.com/alipay.trade.wap.pay-PHP-UTF-8/return_url.php
// jk.mrwangqi.com
//编码格式
'charset' => "UTF-8",
//签名方式
'sign_type'=>"RSA2",
//支付宝网关
'gatewayUrl' => "https://openapi.alipay.com/gateway.do",
//支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
'alipay_public_key' => "",
);
配置完成后,修改demo权限
sudo chmod -R 777 alipayDemo
Посетите index.php в демо-версии
Таким образом, демо может быть запущено.
конкретное развитие
Загрузите SDK прямо сейчас:Мобильный сайт Alipay для оплаты PHP SDK
1. Знакомство с пакетом SDK
Шаги по внедрению пакета SDK в laravel:
- Создайте новую папку libs в app/ и поместите пакет SDK в этот каталог.
2. Найдите файл composer.json в корневом каталоге и добавьте следующую конфигурацию:
"autoload": {
"classmap": [
"database",
"app/libs/alipay" //这里是自定义包的文件位置,我将我项目中的该SDK包命名为alipay
],
"psr-4": {
"App\\": "app/"
}
},
3. Выполните следующую команду
composer dump-autoload //当在包中加入新的类,需要更新autoloader
2. Переместить/Новый файл
Создайте новый каталог wappay в каталоге alipay и создайте два новых каталога, buildermodel и service, в каталоге wappay. Скопируйте файлы wappay/buildermodel/AlipayTradeWapPayContentBuilder.php и wappay/service/AlipayTradeService.php из демонстрационного каталога выше в соответствующие каталоги во вновь созданном wappay в пакете SDK вашего собственного проекта.
AlipayTradeWapPayContentBuilder.php — это инкапсуляция бизнес-параметров демоверсии Alipay платежного интерфейса мобильного веб-сайта Alipay. AlipayTradeService.php — это инкапсуляция бизнес-функции платежного интерфейса демо-версии Alipay мобильного веб-сайта Alipay.
Создайте файл log.txt в каталоге SDK. Хранить файлы как журналы платежей Alipay
3. Настроить/ввести пространство имен
Установите пространство имен AlipayTradeWapPayContentBuilder.php и AlipayTradeService.php, я установил
namespace App\libs\alipay\wappay\buildermodel;
namespace App\libs\alipay\wappay\buildermodel;
Установите пространства имен для alipay/aop/request/AlipayTradeWapPayRequest.php и alipay/aop/AopClient.php, что я установил:
namespace App\libs\alipay\aop\request;
namespace App\libs\alipay\aop;
Внесите два вышеуказанных пространства имен в AlipayTradeWapPayContentBuilder.php:
use App\libs\alipay\aop\request\AlipayTradeWapPayRequest;
use App\libs\alipay\aop\AopClient;
Прокомментируйте следующий код в AlipayTradeService.php:
// require_once dirname ( __FILE__ ).DIRECTORY_SEPARATOR.'./../../AopSdk.php';
// require dirname ( __FILE__ ).DIRECTORY_SEPARATOR.'./../../config.php';
4. Настроить конфиг (alipay.php)
В приведенной выше демонстрации alipay в качестве файла конфигурации присутствует файл config.php.Здесь этот файл нам не нужен.Мы используем возможности laravel для создания нового alipay.php в каталоге config в каталоге проекта laravel:
return [
//应用ID,您的APPID。
'app_id' => "",
//商户私钥,您的原始格式RSA私钥
'merchant_private_key' => "",
//异步通知地址
'notify_url' => "",
//http://工程公网访问地址/alipay.trade.wap.pay-PHP-UTF-8/notify_url.php
//同步跳转
'return_url' => "",
//http://mitsein.com/alipay.trade.wap.pay-PHP-UTF-8/return_url.php
// jk.mrwangqi.com
//编码格式
'charset' => "UTF-8",
//签名方式
'sign_type'=>"RSA2",
//支付宝网关
'gatewayUrl' => "https://openapi.alipay.com/gateway.do",
//支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
'alipay_public_key' => "",
];
5. Соответствует функции модификации конфигурации
Настройте необходимые параметры платежного интерфейса в alipay.php. Ниже мы модифицируем alipay/wappay/service/AlipayTradeService.php:
class AlipayTradeService {
//支付宝网关地址
public $gateway_url = "https://openapi.alipay.com/gateway.do";
//支付宝公钥
public $alipay_public_key;
//商户私钥
public $private_key;
//应用id
public $appid;
//编码格式
public $charset = "UTF-8";
public $token = NULL;
//返回数据格式
public $format = "json";
//签名方式
public $signtype = "RSA";
function __construct(){
$this->gateway_url = config('alipay.gatewayUrl'); //获得config文件夹下的alipay.php中的gatewayUrl参数,下同。
$this->appid = config('alipay.app_id');
$this->private_key = config('alipay.merchant_private_key');
$this->alipay_public_key = config('alipay.alipay_public_key');
$this->charset = config('alipay.charset');
$this->signtype= config('alipay.sign_type');
if(empty($this->appid)||trim($this->appid)==""){
throw new Exception("appid should not be NULL!");
}
if(empty($this->private_key)||trim($this->private_key)==""){
throw new Exception("private_key should not be NULL!");
}
if(empty($this->alipay_public_key)||trim($this->alipay_public_key)==""){
throw new Exception("alipay_public_key should not be NULL!");
}
if(empty($this->charset)||trim($this->charset)==""){
throw new Exception("charset should not be NULL!");
}
if(empty($this->gateway_url)||trim($this->gateway_url)==""){
throw new Exception("gateway_url should not be NULL!");
}
}
function AlipayWapPayService($alipay_config) {
$this->__construct($alipay_config);
}
/**
* alipay.trade.wap.pay
* @param $builder 业务参数,使用buildmodel中的对象生成。
* @param $return_url 同步跳转地址,公网可访问
* @param $notify_url 异步通知地址,公网可以访问
* @return $response 支付宝返回的信息
*/
function wapPay($builder,$return_url,$notify_url) {
$biz_content=$builder->getBizContent();
//打印业务参数
$this->writeLog($biz_content);
$request = new AlipayTradeWapPayRequest();
$request->setNotifyUrl($notify_url);
$request->setReturnUrl($return_url);
$request->setBizContent ( $biz_content );
// 首先调用支付api
$response = $this->aopclientRequestExecute ($request,true);
// $response = $response->alipay_trade_wap_pay_response;
return $response;
}
function aopclientRequestExecute($request,$ispage=false) {
$aop = new AopClient ();
$aop->gatewayUrl = $this->gateway_url;
$aop->appId = $this->appid;
$aop->rsaPrivateKey = $this->private_key;
$aop->alipayrsaPublicKey = $this->alipay_public_key;
$aop->apiVersion ="1.0";
$aop->postCharset = $this->charset;
$aop->format= $this->format;
$aop->signType=$this->signtype;
// 开启页面信息输出
$aop->debugInfo=true;
if($ispage)
{
$result = $aop->pageExecute($request,"post");
echo $result;
}
else
{
$result = $aop->Execute($request);
}
//打开后,将报文写入log文件
$this->writeLog("response: ".var_export($result,true));
return $result;
}
//请确保项目文件有可写权限,不然打印不了日志。
function writeLog($text) {
// $text=iconv("GBK", "UTF-8//IGNORE", $text);
//$text = characet ( $text );
file_put_contents ( dirname ( __FILE__ ).DIRECTORY_SEPARATOR."./../../log.txt", date ( "Y-m-d H:i:s" ) . " " . $text . "\r\n", FILE_APPEND );
}
}
?>
Другие интерфейсы временно недоступны, поэтому я их спрячу здесь.
6. Создайте новый контроллер (AlipayController)
php artisan make:controller AlipayController
Поскольку необходимо реализовать оплату через мобильный веб-сайт, необходимо определить платежный интерфейс:
<?php
namespace App\Http\Controllers\User\Alipay;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\libs\alipay\wappay\buildermodel\AlipayTradeWapPayContentBuilder;
use App\libs\alipay\wappay\service\AlipayTradeService;
class AlipayWapController extends Controller {
/**
*支付接口
*/
public function alipayWapPay(Request $request) {
$out_trade_no = getTradeNOString(); //公共方法生成唯一订单号
$subject = 'test'; //数据仅供测试,下同
$total_amount = 0.01;
$body = 'test test!';
$timeout_express="1m";
$payRequestBuilder = new AlipayTradeWapPayContentBuilder();
$payRequestBuilder->setBody($body);
$payRequestBuilder->setSubject($subject);
$payRequestBuilder->setOutTradeNo($out_trade_no);
$payRequestBuilder->setTotalAmount($total_amount);
$payRequestBuilder->setTimeExpress($timeout_express);
$payResponse = new AlipayTradeService();
$result=$payResponse->wapPay($payRequestBuilder,config('alipay.return_url'),config('alipay.notify_url'));
}
/**
*支付同步回调接口,在config/alipay.php的return_url参数进行配置
*/
public function alipayReturn() {
}
/**
*支付异步回调接口,在config/alipay.php的notify_url参数进行配置
*/
public function alipayNotify() {
}
}
7. Определите маршрут
Определение маршрутов платежей и синхронных и асинхронных маршрутов обратного вызова
Route::group(['prefix' => 'alipay'],function() {
Route::get('wappay','AlipayWapController@alipayWapPay');
Route::get('return','AlipayWapController@alipayReturn');
Route::get('notify','AlipayWapController@alipayNotify');
});
Следует отметить, что синхронная маршрутизация вызывается в форме GET, а асинхронная маршрутизация вызывается в форме POST. При вызове платежного интерфейса будут возникать ошибки CSRF. Теперь проще всего использовать промежуточное ПО laravel, чтобы избежать CSRF, в app/Http. /Добавить маршрутизацию в Middleware/VerifyCsrfToken.php
protected $except = [
//
'alipay/pay',
'alipay/return',
'alipay/notify'
];
8. Изменение конфликтов
В это время платежный интерфейс можно вызвать, указав маршрут, но при вызове будет сообщено о следующей ошибке:
Cannot redeclare Encrypt() (previously declared in .../vendor/laravel/lumen-framework/src/helpers.php:126)
//或:
Cannot redeclare Decrypt() (previously declared in .../vendor/laravel/lumen-framework/src/helpers.php:126)
Это связано с тем, что когда Laravel 5 использует Alipay SDK, имена функций шифрования и дешифрования в Laravel и функций шифрования и дешифрования в Alipay SDK, Encrypt()/Decrypt() конфликтуют.
Решение. Просто измените имя функции, определенное в Alipay SDK, и измените имя указанной функции.
Шаги модификации:
Всего в Alipay SDK необходимо изменить три файла:
aop/AopEncrypt.php
aop/AopClient.php
lotusphp_runtime/Cookie/Cookie.php
Найдите в файле encrypt/decrypt и замените его на alipayEncrypt/alipayDecrypt.
Примечание: Если сервер находится под Linux, может появиться сообщение об ошибке без разрешения, потому что мы создали новый файл log.txt в пакете SDK и функцию writeLog() в alipay/wappay/service/AlipayTradeService.php. нет разрешения на запись при записи журнала платежей в этот файл, просто дайте ему разрешение.
Заканчивать
На данный момент реализована функция оплаты мобильного веб-сайта Alipay в Laravel.Если есть какие-либо недостатки, обращайтесь.