All Projects → TheNorthMemory → easyalipay

TheNorthMemory / easyalipay

Licence: MIT license
支付宝 [A]Sync Chainable Alipay OpenAPI SDK for PHP

Programming Languages

PHP
23972 projects - #3 most used programming language
Makefile
30231 projects

Projects that are alternatives of or similar to easyalipay

alipay kit
flutter版支付宝登录/支付
Stars: ✭ 240 (+1500%)
Mutual labels:  alipay
forum live-tangshan
django后台,移动app,功能有登录,支付、充值,礼物贴现申请,直播,论坛,好友,地区选择功能。
Stars: ✭ 38 (+153.33%)
Mutual labels:  alipay
AndroidNotificationDispatcher
用于监控 Android 支付宝与微信的收款通知
Stars: ✭ 28 (+86.67%)
Mutual labels:  alipay
sy flutter alipay
支付宝flutter插件
Stars: ✭ 86 (+473.33%)
Mutual labels:  alipay
LeXun.Security.OAuth
用于 Asp.Net 和 Asp.Net Core 的OAuth2社交身份验证提供程序。支持支付宝,QQ,微信,百度等第三方登录
Stars: ✭ 19 (+26.67%)
Mutual labels:  alipay
alipay
laravel lumen alipay 最简单,最安全,无验签,支付宝转账支付
Stars: ✭ 18 (+20%)
Mutual labels:  alipay
react-native-alipay
基于 React Native 的宝支付包,已更新到最新的支付宝 SDK 版本,支持Android/iOS。
Stars: ✭ 166 (+1006.67%)
Mutual labels:  alipay
aliqrcode
自动批量生成支付宝收款码工具
Stars: ✭ 45 (+200%)
Mutual labels:  alipay
donate
捐赠我们
Stars: ✭ 12 (-20%)
Mutual labels:  alipay
YHThirdManager
一个快速、简单、易集成、扩展性好的社交化组件。摒弃友盟等三方库,使用原生SDK。支持微信支付、微信分享、微信登录、微信授权、QQ授权、QQ分享、QQ登录、新浪授权、新浪登录、新浪分享、微博评论、微博获取、支付宝支付。极大的减小了包体积;同时加入了自动管理提示框的功能
Stars: ✭ 41 (+173.33%)
Mutual labels:  alipay
openapplus
专为小程序共享而生的小程序容器
Stars: ✭ 51 (+240%)
Mutual labels:  alipay
A3Mall
A3Mall B2C开源商城系统使用Thinkphp6开源框架,前端采用uniapp开发,支持微信公众号商城、H5商城、小程序商城、APP商城、PC商城,前后端源码100%开源,支持免费商用。
Stars: ✭ 142 (+846.67%)
Mutual labels:  alipay
EP-WechatApp
EATER PLANET吃货星球:社区团购电商微信小程序前端(长期维护更新)
Stars: ✭ 154 (+926.67%)
Mutual labels:  alipay
mpapi
🐤 小程序API兼容插件,一次编写,多端运行。支持:微信小程序、支付宝小程序、百度智能小程序、字节跳动小程序
Stars: ✭ 40 (+166.67%)
Mutual labels:  alipay
awesome-cml
awesome for chameleon
Stars: ✭ 66 (+340%)
Mutual labels:  alipay
ZmopSharp
ZMOP (芝麻信用开放平台) SDK for .NET
Stars: ✭ 11 (-26.67%)
Mutual labels:  alipay
AppPay
💸 AppPay专注于App支付的库,几句代码轻松搞定微信支付、支付宝支付。集成更简单。
Stars: ✭ 33 (+120%)
Mutual labels:  alipay
payjs
基于 PAYJS 微信支付个人接口开发的 Package,可直接用于生产环境
Stars: ✭ 73 (+386.67%)
Mutual labels:  alipay
exit-app
☘️ 微信或支付宝点击返回键退出应用程序。
Stars: ✭ 16 (+6.67%)
Mutual labels:  alipay
AlipayOpenapiCpp
支付宝开放平台的C\C++版接入示例代码,包含加签验签\网络请求\参数组装\报文解析等等;仅供商户或开发者参考使用;
Stars: ✭ 44 (+193.33%)
Mutual labels:  alipay

支付宝 Alipay OpenAPI SDK

[A]Sync Chainable Alipay OpenAPI SDK for PHP

GitHub actions Version PHP Version License

概览

支付宝 OpenAPI 的Guzzle HttpClient封装组合, 内置 请求签名应答验签 两个middlewares中间件,创新性地实现了链式面向对象同步/异步调用远程接口。

如果你是使用 Guzzle 的商户开发者,可以使用 EasyAlipay\Builder::factory 工厂方法直接创建一个 GuzzleHttp\Client 的链式调用封装器, 实例在执行请求时将自动携带身份认证信息,并检查应答的支付宝的返回签名。

环境要求

我们开发和测试使用的环境如下:

  • PHP >=7.1.2
  • guzzlehttp/guzzle ^6.5 || ^7.0

注:

  • 兼容支持Guzzle6的PHP最低版本为7.1.2,另PHP官方已于1 Dec 2019停止维护PHP7.1,详见附注链接;
  • Guzzle7支持的PHP最低版本为7.2.5,另PHP官方已于30 Nov 2020停止维护PHP7.2,详见附注链接;

安装

推荐使用PHP包管理工具composer引入SDK到项目中:

方式一

在项目目录中,通过composer命令行添加:

composer require easyalipay/easyalipay

方式二

在项目的composer.json中加入以下配置:

"require": {
    "easyalipay/easyalipay": "^0.3"
}

添加配置后,执行安装

composer install

约定

本类库是以 OpenAPI 公共请求参数中的接入方法 method.做切分,映射成attributes,编码书写方式有如下约定:

  1. 请求 接入方法 method 切分后的每个attributes,可直接以对象获取形式串接,例如 alipay.trade.query 即串成 alipay->trade->query;
  2. 每个 接入方法 method 所支持的 HTTP METHOD,即作为被串接对象的末尾执行方法,例如: alipay->trade->query->post(['content' => []]);
  3. 每个 接入方法 method 所支持的 HTTP METHOD,同时支持Async语法糖,例如: alipay->trade->query->postAsync(['content' => []]);
  4. 每个 接入方法 method 可以使用PascalCase风格书写,例如: alipay.trade.query可写成 AlipayTradeQuery;
  5. 在IDE集成环境下,也可以按照内置的chain($method)接口规范,直接以接入方法 method作为变量入参,来获取OpenAPI当前接入方法的实例,驱动末尾执行方法(填入对应参数),发起请求,例如 chain('alipay.trade.query')->post(['content' => []])
  6. 末尾get/post/getAsync/postAsync请求方法语法糖,型参$options语法糖规则如下:
    1. content字典,对应的是请求参数集合(biz_content)字典,直接写原生PHP array即可;
    2. query字典,对应的是除请求参数集合(biz_content)之外的,如部分特殊公共请求参数(system_params)通知地址(notify_url)等,直接写原生PHP array即可;
    3. 一个入参时$options按需带入'content' => [] 及/或 'query' => []结构即可;
    4. 简写语法糖支持[get|post][Async](array $content, array $options)[get|post][Async](array $content, array $query, array $options)结构;
    5. 本SDK所有请求数据结构遵循官方开发文档,该是蛇型即蛇形(如:service_code),该是驼峰就驼峰(如:shopIds),看到的数据结构,即请求数据结构,原生PHP语法即可;
  7. 内置返回值验签中间件在解构原始json字符串后,直接返回*_response对应的内容,有可能是json,也可能是AesCbc加密串,按需对返回串做处理;

以下示例用法,以异步(Async/PromiseA+)同步(Sync)结合此种编码模式展开。

开始

首先,通过 EasyAlipay\Builder::factory 工厂方法构建一个实例,然后如上述约定,链式同步异步请求远端OpenAPI接口。

use EasyAlipay\Builder;
use EasyAlipay\Crypto\Rsa;

//应用app_id
$appId = '2014072300007148';

//商户RSA私钥,入参是'从官方工具获取到的BASE64字符串'
$privateKey = Rsa::fromPkcs1('MIIEpAIBAAKCAQEApdXuft3as2x...');
// 以上是下列代码的语法糖,格式为 'private.pkcs1://' + '从官方工具获取到的字符串'
// $privateKey = Rsa::from('private.pkcs1://MIIEpAIBAAKCAQEApdXuft3as2x...');
// 也支持以下方式,须保证`private_key.pem`为完整X509格式
// $privateKey = Rsa::from('file:///your/openapi/private_key.pem');

//支付宝RSA公钥,入参是'从官方工具获取到的BASE64字符串'
$publicKey = Rsa::fromSpki('MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCg...');
// 以上是下列代码的语法糖,格式为 'public.spki://' + '从官方工具获取到的字符串'
// $publicKey = Rsa::from('public.spki://MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCg...', Rsa::KEY_TYPE_PUBLIC);
// 也支持以下方式,须保证`public_key.pem`为完整X509格式
// $publicKey = Rsa::from('file:///the/alipay/public_key.pem', Rsa::KEY_TYPE_PUBLIC);

//如果是公钥证书模式,可以在工厂方法内传入 `$appCertSn` 及 `$alipayRootCertSn`
// $appCertFilePath = '/my/cert/app_cert.crt';
// $appCertSn = \EasyAlipay\Helpers::sn($appCertFilePath);
// $alipayRootCertFilePath = '/alipay/cert/alipayRootCert.crt';
// $alipayRootCertSn = \EasyAlipay\Helpers::sn($alipayRootCertFilePath);

// 工厂方法构造一个实例
$instance = Builder::factory([
    'privateKey' => $privateKey,
    'publicKey' => $publicKey,
    'params' => [
        'app_id' => $appId,
        // 'app_auth_token' => $appAuthToken,
        // 'app_cert_sn' => $appCertSn,
        // 'alipay_root_cert_sn' => $alipayRootCertSn,
    ],
]);

初始化字典说明如下:

  • privateKey商户API私钥,一般是通过官方证书生成工具生成字符串,支持PKCS#1PKCS#8格式的私钥加载;
  • publicKey平台API公钥,一般是通过官方证书生成工具生成字符串,支持PKCS#8SPKI格式的公钥加载;
  • params 接口中的公共请求参数配置项,已内置charset=UTF-8, format=JSON, sign_type=RSA2version=1.0
  • params['app_id' => $appId] 为你的应用app_id
  • params['app_auth_token' => $appAuthToken] 为你的ISV模式的授权token,按需配置;
  • params['app_cert_sn' => $appCertSn]公钥证书模式的商户证书相关信息SN,按需配置;
  • params['alipay_root_cert_sn' => $alipayRootCertSn]公钥证书模式的平台证书相关信息SN,按需配置;

注: OpenAPI 以及 GuzzleHttp\Clientarray $config 初始化参数,均融合在一个型参上。

统一收单线下交易查询

use GuzzleHttp\Utils;
use GuzzleHttp\Exception\RequestException;

try {
    $res = $instance
    ->alipay->trade->query
    ->get(['content' => [
        'out_trade_no' => '20150320010101001',
    ]]);

    echo $res->getBody(), PHP_EOL;
} catch (RequestException $e) {
    // 进行错误处理
    if ($e->hasResponse()) {
        $r = $e->getResponse();
        echo $r->getStatusCode() . ' ' . $r->getReasonPhrase(), PHP_EOL;
        echo $r->getBody(), PHP_EOL, PHP_EOL, PHP_EOL;
    }
} catch (\Throwable $e) {
    // 进行错误处理
    echo $e->getMessage(), PHP_EOL;
    echo $e->getTraceAsString(), PHP_EOL;
}

统一收单交易支付接口

use GuzzleHttp\Utils;
use GuzzleHttp\Exception\RequestException;
use Psr\Http\Message\ResponseInterface;

$res = $instance
->alipay->trade->pay
->postAsync(['content' => [
    'out_trade_no' => '20150320010101001',
    'scene'        => 'bar_code',
    'auth_code'    => '28763443825664394',
    'product_code' => 'FACE_TO_FACE_PAYMENT',
    'subject'      => 'Iphone6 16G',
    'total_amount' => '88.88',
]])
->then(static function(ResponseInterface $response) {
    // 正常逻辑回调处理
    return Utils::jsonDecode((string) $response->getBody(), true);
})
->otherwise(static function($e) {
    // 异常错误处理
    echo $e->getMessage(), PHP_EOL;
    if ($e instanceof RequestException && $e->hasResponse()) {
        $r = $e->getResponse();
        echo $r->getStatusCode() . ' ' . $r->getReasonPhrase(), PHP_EOL;
        echo $r->getBody(), PHP_EOL, PHP_EOL, PHP_EOL;
    }
    echo $e->getTraceAsString(), PHP_EOL;
})
->wait();
print_r($res);

统一收单线下交易预创建

use GuzzleHttp\Utils;
use GuzzleHttp\Exception\RequestException;
use Psr\Http\Message\ResponseInterface;

$res = $instance
->Alipay->Trade->Precreate
->postAsync([
    'out_trade_no' => '20150320010101001',
    'subject'      => 'Iphone6 16G',
    'total_amount' => '88.88',
], ['query' => [
    'notify_url' => 'http://api.test.alipay.net/atinterface/receive_notify.htm'
]])
->then(static function(ResponseInterface $response) {
    // 正常逻辑回调处理
    return Utils::jsonDecode((string) $response->getBody(), true);
})
->otherwise(static function($e) {
    // 异常错误处理
})
->wait();
print_r($res);

手机网站支付接口2.0

use Psr\Http\Message\ResponseInterface;

$res = $instance
->chain('alipay.trade.wap.pay')
->postAsync([
    'subject'      => '商品名称',
    'out_trade_no' => '22',
    'total_amount' => '0.01',
    'product_code' => 'FAST_INSTANT_TRADE_PAY',
    'quit_url'     => 'https://forum.alipay.com/mini-app/post/15501011',
], ['pager' => true])
->then(static function(ResponseInterface $response) {
    // 正常逻辑回调处理
    return (string) $response->getBody();
})
->otherwise(static function($e) {
    // 异常错误处理
})
->wait();
print_r($res);

统一收单下单并支付页面接口

use GuzzleHttp\Utils;
use GuzzleHttp\Exception\RequestException;

try {
    $res = $instance['alipay.trade.page.pay']
    ->post(['content' => [
        'subject'      => '商品名称',
        'out_trade_no' => '22',
        'total_amount' => '0.01',
        'product_code' => 'FAST_INSTANT_TRADE_PAY',
    ], 'pager' => true]);
    echo $resp->getBody(), PHP_EOL;
} catch (RequestException $e) {
    // 进行错误处理
} catch (\Throwable $e) {
    // 异常错误处理
}

上传门店照片和视频接口

use GuzzleHttp\Utils;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Psr\MultipartStream;
use Psr\Http\Message\ResponseInterface;

$media = new MultipartStream([
    'name'     => 'image_content',
    'contents' => 'file:///path/for/uploading.jpg',
]);

$res = $instance
->chain('alipay.offline.material.image.upload')
->postAsync([
    'body' => $media,
])
->then(static function(ResponseInterface $response) {
    // 正常逻辑回调处理
    return Utils::jsonDecode((string) $response->getBody(), true);
})
->otherwise(static function($e) {
    // 异常错误处理
})
->wait();
print_r($res);

敏感信息加/解密

use EasyAlipay\Crypto\AesCbc;
use GuzzleHttp\Utils;
use Psr\Http\Message\ResponseInterface;

$aesCipherKey = '';

$res = $instance
->chain('some.method.response.by.aes.encrypted')
->postAsync([])
->then(static function(ResponseInterface $response) use ($aesCipherKey) {
    $json = Utils::jsonDecode((string) $response->getBody());
    return AesCbc::decrypt((string) $json->response, $aesCipherKey);
})
->wait();
print_r($res);

链接

许可证

MIT

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].