app_id = config('wxmp_config.app_id'); $this->secret = config('wxmp_config.secret'); } // 获取微信小程序支付订单参数 public function getWxmpPay($pay_type, $data){ if(empty($pay_type)){ return ['code' => 100, 'data' => [], 'msg' => '缺少必要参数:pay_type']; } if(empty($data['title'])){ return ['code' => 100, 'data' => [], 'msg' => '缺少必要参数:title']; } if(empty($data['order_id'])){ return ['code' => 100, 'data' => [], 'msg' => '缺少必要参数:order_id']; } if(empty($data['amount'])){ return ['code' => 100, 'data' => [], 'msg' => '缺少必要参数:amount']; } if(empty($data['open_id'])){ return ['code' => 100, 'data' => [], 'msg' => '缺少必要参数:open_id']; } $orderInfo = Cache::store('redis')->get($this->order_prefix.$data['order_id']); if(!$orderInfo){ return ['code' => 100, 'data' => [], 'msg' => '订单号有误,请重新支付!']; } // $data = [ // 'title' => 'xxx', // 'amount' => 'xxx', // 'game_id' => 'xxx', // 'is_coin' => 'xxx', // ]; $config = Config::get('ldys_pay'); $orderInfo = json_decode($orderInfo, true); $notify_url = $config['notify'][$pay_type]['notify_url']; if (!empty($orderInfo['is_coin']) && $orderInfo['is_coin'] == 1) { $notify_url = $config['notify'][$pay_type]['notify_coin_url']; } $params = [ "mer_id" => $config['mer_id'], "notify_url" => $notify_url, "amt_type" => "RMB", "goods_inf" => $data['title'], "order_id" => $data['order_id'], "mer_date" => date("Ymd"), "amount" => formatYuanToFen($data['amount']), // 分 "user_ip" => getUserIp(), "open_id" => $data['open_id'], "app_id" => $config['app_id'], "scancode_type" => "WECHAT", "mer_flag" => "KMER", ]; log_message('# '. $data['order_id'].' : ' . json_encode($params), 'log', LOG_PATH . 'three/ldys_pay/'); $service = new UmfService($config['mer_id']); $res = $service->miniProgramPayMap($params); /** * *
array(13) {
* ["app_id"]=>
* string(18) "wx117849d0c0632d22"
* ["bank_seq"]=>
* string(0) ""
* ["mer_date"]=>
* string(8) "20240425"
* ["mer_id"]=>
* string(5) "55282"
* ["nonce_str"]=>
* string(32) "7a9effbfe6324e089de9feb49c5f019f"
* ["order_id"]=>
* string(9) "633876442"
* ["package"]=>
* string(46) "prepay_id=wx25163615048261aa76cccf65807c9b0000"
* ["pay_sign"]=>
* string(344) "eHqSBYowy6LjbDYcHCcuh1GpY8K+mndcSU/WgWzmJlHWeUgefcix8yniZq4vVvgdODc2dZTwenPZa4hJhbp0Vw9x8uW6jb+GnlziJRZzj1mfer84UgoFh5iZy00mkBobe9VMdyZIFSbIhp41ICFpJulIFPqqrZ6T+kB4rw/kRkYNf7Px48w8XUWB2uGvLllUhjGQMdmnkULBO6x246GaXs2x6BFQbDxShOTX7KI48Whp6d4ZbJhLTSXUhN4N+6cKf7OH2jZNk/crBoQobQT4hhhUYnR44dIXimFsjLXCh+TQ5ZiNSw9xnj5Q7ER40ncl/5GSqectmtG4hCmrCv3xDg=="
* ["ret_code"]=>
* string(4) "0000"
* ["ret_msg"]=>
* string(12) "交易成功"
* ["time_stamp"]=>
* string(10) "1714034175"
* ["trade_no"]=>
* string(16) "3404251636078494"
* ["weixin_sign_type"]=>
* string(3) "RSA"
* }
*/
if ($res['ret_code'] == '00060780') {
return ['code' => 110, 'data' => [], 'msg' => '订单已支付成功,无须再次支付'];
}
if ($res['ret_code'] != '0000') {
// TODO: 钉钉通知
return ['code' => 120, 'data' => [], 'msg' => $res['ret_msg']];
}
$res = [
'timeStamp' => $res['time_stamp'],
'nonceStr' => $res['nonce_str'],
'package' => $res['package'],
'signType' => $res['weixin_sign_type'],
'paySign' => $res['pay_sign'],
];
return ['code' => 200, 'data' => $res, 'msg' => 'success'];
}
// 生成微信下单URL
public function generateWxmpPayUrl($order_id, $game_id){
// return ['error' => false, 'data' => 'https://wxaurl.cn/qmyZ8gwAjKv', 'msg' => 'success'];
try {
$access_token = $this->getWxToekn();
$env_version = 'release';
// if(config('app_status') == 'dev'){
// $env_version = 'develop';
// }
$data = [
'path' => '/pages/index/pay',
'is_expire' => true,
'query' => "order_id={$order_id}&game_id={$game_id}",
'expire_type' => 0,
'expire_time' => time() + 300,
// 'expire_type' => 1,
// 'expire_interval' => 1,
'env_version' => $env_version, // 默认值"release"。要打开的小程序版本。正式版为 "release",体验版为"trial",开发版为"develop",仅在微信外打开时生效。
];
$res = getHttpPost("https://api.weixin.qq.com/wxa/generate_urllink?access_token=" . $access_token, json_encode($data));
$res = json_decode($res, true);
if ($res['errcode'] !== 0 || empty($res['url_link'])) {
return ['error' => true, 'data' => [], 'msg' => '001-1_LdysPay_生成微信URL失败'];
}
}catch (Exception $e) {
// dump($e->getMessage(), $e->getFile(), $e->getLine());
return ['error' => true, 'data' => [], 'msg' => '001-2_LdysPay_生成微信URL失败.Exception:' . $e->getMessage()];
}
return ['error' => false, 'data' => $res['url_link'], 'msg' => 'success'];
}
// 获取微信Token
public function getWxToekn(){
$cache_key = 'wx_token:'.$this->app_id;
$token = Cache::get($cache_key);
if(!$token){
$res = getHttpGet("https://api.weixin.qq.com/cgi-bin/token", [
'grant_type' => 'client_credential',
'appid' => $this->app_id,
'secret' => $this->secret
]);
$res = json_decode($res, true);
Cache::set($cache_key, $res['access_token'], $res['expires_in']-30);
$token = $res['access_token'];
}
return $token;
}
// 记录订单
public function recordOrder($order_id, $data){
$payUrl = '';
try {
$urlResult = $this->generateWxmpPayUrl($order_id, $data['game_id']);
if($urlResult['error'] == true){
return ['error' => true, 'data' => [], 'msg' => "001_".$urlResult['msg']];
}
$payUrl = $urlResult['data'];
Cache::store('redis')->set($this->order_prefix.$order_id, json_encode($data), 300);
}catch (Exception $e) {
return ['error' => true, 'data' => [], 'msg' => '002_LdysPay_下单失败:'.$e->getMessage()];
}
return ['error' => false, 'data' => ['pay_url' => $payUrl], 'msg' => 'success'];
}
// 查询订单
public function queryOrder($order_id){
try {
$result = Cache::store('redis')->get($this->order_prefix.$order_id);
if(!$result){
return ['error' => true, 'data' => [], 'msg' => '当前订单已过期或不存在!'];
}
}catch (Exception $e) {
return ['error' => true, 'data' => [], 'msg' => '查询失败!'];
}
return ['error' => false, 'data' => json_decode($result, true), 'msg' => 'success'];;
}
// 回调处理
public function notify(){
$data = request()->only([
"amount", "amt_type", "bank_mer_id", "bank_trace", "charset", "error_code", "media_type", "mer_date", "mer_id", "open_id", "order_id", "pay_date", "pay_seq", "pay_success_time", "pay_type", "service", "settle_date", "trade_no", "trade_state", "version", "sign", "sign_type"
]);
$notifyParamsStr = http_build_query($data);
$config = Config::get('ldys_pay');
$service = new UmfService($config['mer_id']);
$array = $service->notifyDataParserMap($notifyParamsStr);
$mer2UmfPlatStr = $service->responseUMFMap($array, $config['private_file']);
$resultStr = '';
if ($array === false) {
return ['error' => true, 'data' => ['result' => '', 'data' => $resultStr], 'msg' => '回调效验失败!'];
}
return ['error' => false, 'data' => $resultStr, 'msg' => 'success'];
}
public function getWxH5Pay($pay_type, $data)
{
try {
$config = Config::get('ldys_pay');
$notify_url = $config['notify'][$pay_type]['notify_url'];
if (!empty($data['is_coin']) && $data['is_coin'] == 1) {
$notify_url = $config['notify'][$pay_type]['notify_coin_url'];
}
// 预下载
$params = array(
"mer_id" => $config['mer_id'],
"notify_url" => $notify_url,
"order_id" => $data['orderid'],
"mer_date" => date("Ymd"),
"amount" => formatYuanToFen($data['real_amount']), // 分
"user_ip" => getUserIp(),
"goods_inf" => $data['productname'],
"pay_type" => 2, // 支付类型: 1=支付宝, 2=微信支付, 3=微信云闪付
"page_order_type" => "H5",
"mer_flag" => "KMER",
"consumer_id" => $data['userid'], // 消费者ID
"app_id" => $config['app_id'],
);
$service = new UmfService($config['mer_id']);
$result = $service->appOrderMap($params);
if ($result['ret_code'] == '0000') {
return ['code' => 200, 'data' => ['pay_url' => $result['page_link']], 'msg' => 'success'];
}
// TODO: 钉钉通知
return ['code' => 110, 'data' => [], 'msg' => $result['ret_msg']];
} catch (Exception $e) {
return ['code' => 120, 'data' => [], 'msg' => '下单失败: ' . $e->getMessage()];
}
}
}