323 lines
13 KiB
PHP
323 lines
13 KiB
PHP
<?php
|
||
namespace app\common\server\platform;
|
||
|
||
use Alipay\EasySDK\Kernel\Factory;
|
||
use Alipay\EasySDK\Kernel\Config;
|
||
use app\common\model\User;
|
||
use think\App;
|
||
use think\facade\Db;
|
||
use think\facade\Log;
|
||
use app\common\model\Order;
|
||
use app\common\model\OrderNotify;
|
||
use app\common\helper\EnvHelper;
|
||
use think\facade\Request;
|
||
/**
|
||
* 多端平台支付抽象基类
|
||
*/
|
||
class AppPlatform extends BasePlatform
|
||
{
|
||
public function __construct()
|
||
{
|
||
parent::__construct();
|
||
$this->code = 'APP_ANDROID';
|
||
$this->env = 'app';
|
||
Factory::setOptions($this->getOptions());
|
||
}
|
||
|
||
/**
|
||
* 获取系统配置
|
||
* @return void
|
||
*/
|
||
public function get_config(): array
|
||
{
|
||
// 获取订单编号
|
||
$version = Request::param('version', '1.0.0');
|
||
$versionNumber = (int) preg_replace('/[^0-9]/', '', $version);
|
||
$config = [
|
||
'isWebPay' => false,
|
||
'buildVersion' => '106',
|
||
'version' => '1.0.1',
|
||
'userAgreement' => "https://zfunbox.cn?_p=cb20xad0e35094521ae46a1d1fb0ddd1&time=" . time()
|
||
];
|
||
$is_env_test = EnvHelper::getIsTest();
|
||
if ($is_env_test) {
|
||
$config['userAgreement'] = "https://testweb.zfunbox.cn?_p=cb20xad0e35094521ae46a1d1fb0ddd1&time=" . time();
|
||
}
|
||
// $config['userAgreement'] = " https://192.168.1.21:3001?_p=cb20xad0e35094521ae46a1d1fb0ddd1&time=" . time();
|
||
$configVersion = (int) preg_replace('/[^0-9]/', '', $config['version']);
|
||
if ($versionNumber >= $configVersion) {
|
||
$config['buildVersion'] = '105';
|
||
// $config['isCheck'] = true;
|
||
$config['userAgreement'] = "https://zfunbox.cn/pages/guize/guize?type=4";
|
||
|
||
}
|
||
return $config;
|
||
}
|
||
/**
|
||
* Summary of pay
|
||
* @param array $data
|
||
* @throws \Exception
|
||
* @return array|array{data: array, status: int}
|
||
*/
|
||
public function pay(array $data): array
|
||
{
|
||
|
||
|
||
try {
|
||
$data += ['user' => null, 'price' => 0, 'title' => '', 'attach' => 'order_wxs', 'pre' => 'MH_'];
|
||
[
|
||
'user' => $user,
|
||
'price' => $price,
|
||
'title' => $title,
|
||
'attach' => $attach,
|
||
'pre' => $pre,
|
||
'quitUrl' => $quitUrl,
|
||
'returnUrl' => $returnUrl
|
||
] = $data;
|
||
if ($user == null) {
|
||
//抛出异常
|
||
throw new \Exception('用户信息为空');
|
||
}
|
||
$project_prefix = "AD";
|
||
if ($price <= 0) {
|
||
//生成订单号,订单号为:ML_DRAYDMP02025018.... ML_ 前缀(固定3位),DRA 商户号(固定3位),YD 项目,固定2位,MP0 表示微信小程序支付
|
||
$order_no = create_order_no_new($pre, "MON", $project_prefix, "APP");
|
||
return [
|
||
'status' => 1,
|
||
'data' => [
|
||
'order_no' => $order_no,
|
||
'res' => []
|
||
]
|
||
];
|
||
}
|
||
|
||
$prefix = "ZFA";//$this->GetPrefix();
|
||
$config = $this->get_config();
|
||
if ($config['isWebPay']) {
|
||
$domain = Request::domain();
|
||
// Request::param('return_url')
|
||
$host = parse_url($domain, PHP_URL_HOST);
|
||
$order_no = create_order_no_new($pre, "ZFA", 'H5', "ZFB");
|
||
$extend = [
|
||
'orderType' => $attach,
|
||
];
|
||
$extend_str = json_encode($extend, JSON_UNESCAPED_UNICODE);
|
||
// 将通知URL和随机字符串保存到order_notify表中
|
||
Db::name('order_notify')->insert([
|
||
'order_no' => $order_no,
|
||
'notify_url' => '',
|
||
'nonce_str' => '',
|
||
'pay_time' => date('Y-m-d H:i:s'),
|
||
'pay_amount' => $price,
|
||
'status' => 0,
|
||
'retry_count' => 0,
|
||
'create_time' => date('Y-m-d H:i:s'),
|
||
'update_time' => date('Y-m-d H:i:s'),
|
||
'extend' => $extend_str,
|
||
'title' => $title,
|
||
]);
|
||
return [
|
||
'status' => 1,
|
||
'data' => [
|
||
'order_no' => $order_no,
|
||
'res' => ['data' => ['order_num' => $order_no], 'requestPay' => $domain . '/api/send_web_pay_order', 'tips' => '']
|
||
]
|
||
];
|
||
}
|
||
$title = mb_substr($title, 0, 30);
|
||
|
||
|
||
//生成订单号,订单号为:ML_DRAYDMP02025018.... ML_ 前缀(固定3位),DRA 商户号(固定3位),YD 项目,固定2位,MP0 表示微信小程序支付
|
||
$order_no = create_order_no_new($pre, $prefix, $project_prefix, "ZFB");
|
||
$openid = $user['openid'];
|
||
$payment_type = 'zfbpay';
|
||
$order_type = $attach;
|
||
$user_id = $user ? $user['id'] : 0;
|
||
// 回调使用的随机数(与支付随机数分离)
|
||
$callback_nonce_str = $this->genRandomString();
|
||
// 生成新的支付通知URL
|
||
$notifyUrl = generatePayNotifyUrl($payment_type, $order_type, $user_id, $order_no, $callback_nonce_str);
|
||
$is_env_test = EnvHelper::getIsTest();
|
||
if ($is_env_test) {
|
||
$is_test = $user['istest'];
|
||
if ($is_test == 2) {
|
||
$price = 0.01;
|
||
}
|
||
}
|
||
$returnUrl = urldecode($returnUrl);
|
||
//2. 发起API调用(以支付能力下的统一收单交易创建接口为例)
|
||
$result = Factory::payment()
|
||
->app()
|
||
->asyncNotify($notifyUrl)
|
||
->pay(
|
||
$title, // 支付标题
|
||
$order_no, // 商户订单号(唯一)
|
||
$price, // 金额
|
||
$quitUrl,// 取消地址
|
||
$returnUrl// 支付后返回地址
|
||
);
|
||
//3. 处理响应或异常
|
||
if (!empty($result->body)) {
|
||
// echo "调用成功" . PHP_EOL;
|
||
// 将通知URL和随机字符串保存到order_notify表中
|
||
Db::name('order_notify')->insert([
|
||
'order_no' => $order_no,
|
||
'notify_url' => $notifyUrl,
|
||
'nonce_str' => $callback_nonce_str,
|
||
'pay_time' => date('Y-m-d H:i:s'),
|
||
'pay_amount' => $price,
|
||
'status' => 0,
|
||
'retry_count' => 0,
|
||
'create_time' => date('Y-m-d H:i:s'),
|
||
'update_time' => date('Y-m-d H:i:s'),
|
||
'title' => $title,
|
||
]);
|
||
return [
|
||
'status' => 1,
|
||
'data' => [
|
||
'order_no' => $order_no,
|
||
'res' => $result->body
|
||
]
|
||
];
|
||
} else {
|
||
return ['status' => 0, 'msg' => '支付失败:' . $result];
|
||
}
|
||
} catch (\Exception $e) {
|
||
// echo "调用失败," . $e->getMessage() . PHP_EOL;
|
||
// ;
|
||
}
|
||
return ['status' => 0, 'msg' => '支付失败:'];
|
||
}
|
||
|
||
|
||
/**
|
||
* 客服发送消息
|
||
* @param mixed $user_id
|
||
* @param mixed $order_num
|
||
* @return array{status: int, data: array, msg: string}
|
||
*/
|
||
public function sendCustomerServiceMessage($user, $order_num): array
|
||
{
|
||
// 获取订单编号
|
||
$return_url = Request::param('return_url', '');
|
||
|
||
|
||
$message = "用户ID:{$user['id']},订单号:{$order_num}";
|
||
$order_title = '';
|
||
$order_price = 0;
|
||
if ($user['openid'] == null) {
|
||
return ['status' => 0, 'msg' => '用户openid为空'];
|
||
}
|
||
$orderNotify = OrderNotify::where([
|
||
'order_no' => $order_num,
|
||
])->find();
|
||
$extend = [];
|
||
if ($orderNotify) {
|
||
if ($orderNotify['extend'] != '') {
|
||
$extend = json_decode($orderNotify['extend'], true);
|
||
}
|
||
$order_title = $orderNotify['title'];
|
||
$order_price = $orderNotify['pay_amount'];
|
||
}
|
||
if ($order_title == "") {
|
||
return ['status' => 0, 'msg' => '订单号错误'];
|
||
}
|
||
|
||
// $this->appid
|
||
$web_domain = EnvHelper::getWebDomain();
|
||
$extend['returnUrl'] = $return_url;
|
||
$extend['openId'] = $user['openid'];
|
||
$extend['userId'] = $user['id'];
|
||
$extend_str = json_encode($extend, JSON_UNESCAPED_UNICODE);
|
||
OrderNotify::where('order_no', $order_num)->update(['extend' => $extend_str]);
|
||
return ['status' => 1, 'data' => $web_domain . '/pages/other/web-pay-order?order_num=' . $order_num];
|
||
|
||
}
|
||
|
||
/**
|
||
* 发货
|
||
* @param mixed $openid
|
||
* @param mixed $access_token
|
||
* @param mixed $order_num
|
||
* @param mixed $title
|
||
* @return int
|
||
*/
|
||
public function post_order($user, $order_num): int
|
||
{
|
||
|
||
return 1;
|
||
}
|
||
|
||
public function verify($order_no, $data): bool
|
||
{
|
||
$result = Factory::payment()->common()->verifyNotify($data);
|
||
if ($result) {
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
* 生成URL链接
|
||
* @param int $userId 用户ID
|
||
* @return array
|
||
*/
|
||
public function generateUrlLink($userId): array
|
||
{
|
||
|
||
return ['status' => 1, 'data' => ""];
|
||
}
|
||
|
||
/**
|
||
* 获取手机号
|
||
* @param string $code 手机号获取凭证
|
||
* @return array
|
||
*/
|
||
public function getMobile($code = ''): array
|
||
{
|
||
|
||
|
||
return ['status' => 1, 'data' => ""];
|
||
}
|
||
|
||
/**
|
||
* 获取openid
|
||
* @param string $code 登录凭证
|
||
* @return array
|
||
*/
|
||
public function getOpenid($code): array
|
||
{
|
||
|
||
return ['status' => 1, 'data' => ""];
|
||
}
|
||
|
||
|
||
|
||
public function getOptions()
|
||
{
|
||
$options = new Config();
|
||
$options->protocol = 'https';
|
||
$options->gatewayHost = 'openapi.alipay.com';
|
||
$options->signType = 'RSA2';
|
||
|
||
$options->appId = '2021005164620165';
|
||
|
||
// 为避免私钥随源码泄露,推荐从文件中读取私钥字符串而不是写入源码中
|
||
$options->merchantPrivateKey = 'MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCktwsJYjHNq3q+oJE7U4vnbt3N+DmRigStdSbNXJfkoxISZvwCVbGUZUkERnfQyg59xKTrywogUvW48i2DibuyAkdtZ0jM/kJN0D0u0WsGCZ1afr8EOIJ1tyCrAS79wV2MUGnQ1BLS3e12SAhNme6hgGFqV1WCyHXvsV+i4i3UTBD3Ai7gBv+UmWQ1R4S4oAWNMjIAw+SxYLIkzG7HFq8vGG2wVnL5/vjsy+cydmBhMOZT1ZccLNR2l+SVr9iNN4UPgXuzrHBdLuDAd0MSzSG1q8xClTLeb/MIuHWrj6rbtkAagCKUM+KP3KcKIdAqHfL0LQb3EQ7b3mG4coF8mrrXAgMBAAECggEAXa0cQcHuwSF9NVzsO+lP79dFnhZF51evQVcXMkQuvoFfjce0Gz/RNqxD0oKhMcU4aJ6ljNR0dd24ke5ppB14+cwCA15yMOOJoeeEZFQFofFl5EmhKS1aRMhZc+fAaeDG6z3wcCusaPB+VH6y+i9JX+A7htcUcsS/Dgq6cVBg8BNG5HcREqJFtSQDbIzimndnRpIY3Jq7WxxOjxNzB7WaSxb60XcV5JwOK+YXhTxewXnOBBq0ByDKHKaPAQrC0cHH6B/P39hgZCROoJDXGvRxk14zbxToXlStwxOfFG8Onljq4y11yCRlinQ9+pDwxA7DdG2wS282elKVs8tYC/BpwQKBgQDryCk/p7P0N+Jx0ioeMuhs1br2UqhMjqtWhKoRboO6g8pR5vL8WN+wKQBJYnaaATq63tmk7lUrTbXLH826psgRW4nqpYme/XBjqt6PcBP6LUt54tOBBsYxfjobN0zko7MZ18MlUVGd5UgbuSgKyFncrPjP1BPXPh4hba0Jc/Y4ZQKBgQCy1tXt47zCx9mrcjknnKvhex/Cv/DmgWKYe+j8LWGLVIjOhw3OBnye7DUXjZiOZfJv028PV/Q5lD7ve8Ah/XtPJl6X0OxA4t8NrCfzraInwPk/p9hkShV600oVYoaO9aOWYVdwnMNLNoThl4kbHtffFsmVv5e3W8B4g7CP/unsiwKBgQCwL6YDFwH1oDzp6K3oWworKZrHrgRtEL8fq4qZ9AcjPI/Wm8k+n/qm3DyGmbkeY4TLVvMzt5SVA0CxRFaq/y3JKqnoWUJ5N9Df6TLd5FZJP8eCkOiTJci7+yLYa35d66VNzljYbeebIVW8waMWS5g6ulZClqss0BIb0KTYx3pZsQKBgHpDLVXJD88J2eG/4RsXnNo11mzJ0+OCKOmeLJXaYIlkbXLkGafz/1aWnWVQxC71u1x/67lNpAWJN815iMy0Ao0F6j1X82wYre0m+Nk6p1UONFg0Y1eM3kpuEIO2K8+oVwID4kd2pHzS9N1VP8Juv54gcggSR6Ju85JwVVDcMQgpAoGBAIqXHdLgAqBwe4Q/wT94DVL93mQ1JQKCF2SEN/AxduA08aBXje/m4ZOGbWf4aTqSQN5LWPR6udzR5zCY7YtT2/eZbIrMxzrEG3M4gztIV11+QttxC1yB040hLyaKcnuqNEWKyPlUOz32TYNbXVY9xKY5esp6wlSTPhd7ys4LgGzv';
|
||
|
||
// $options->alipayCertPath = '<-- 请填写您的支付宝公钥证书文件路径,例如:/foo/alipayCertPublicKey_RSA2.crt -->';
|
||
// $options->alipayRootCertPath = '<-- 请填写您的支付宝根证书文件路径,例如:/foo/alipayRootCert.crt" -->';
|
||
// $options->merchantCertPath = '<-- 请填写您的应用公钥证书文件路径,例如:/foo/appCertPublicKey_2019051064521003.crt -->';
|
||
|
||
//注:如果采用非证书模式,则无需赋值上面的三个证书路径,改为赋值如下的支付宝公钥字符串即可
|
||
$options->alipayPublicKey = 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAl09lU/ezb0ZaNgmlOVp01ZruPdolQgTcV9a42vUv3tYImBGWMGuGF555YGV5yHLVUmHaF0fh6AYWhxOe9iZTlp20vKctkmSVBpjE1UJXlLgn/5L0nzy08+wFCvJ0v3D8/ZwJ4nryjx6rfKbzs+/Ub5X2XuMJj4IhficN/T9tJAWmn8tfccWVw+DGgouIbcCftuGvbOZOAmqzGHU0ZYZXNjCqKithZjO9/9exbA0/5NkETFZqJEDVi09WZ7OS8B0twAPqEnnmYCGb0t8Tn+g1qoWaA/uU3ysQrrQk+q2Xl/PwOT07pCkAgFg4akUQ/poWA9yx2kDnq+3NJxiE0PoIrQIDAQAB';
|
||
//可设置异步通知接收服务地址(可选)
|
||
//如果需要使用文件上传接口,请不要设置该参数
|
||
$options->notifyUrl = "";
|
||
|
||
//可设置AES密钥,调用AES加解密相关接口时需要(可选)
|
||
// $options->encryptKey = "<-- 请填写您的AES密钥,例如:aa4BtZ4tspm2wnXLb1ThQA== -->";
|
||
return $options;
|
||
}
|
||
|
||
} |