| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295 |
- <?php
- namespace XiTaiYouPay;
- use XiTaiYouPay\util\RSAUtil;
- use XiTaiYouPay\util\ParameterUtil;
- use XiTaiYouPay\util\HttpRequestUtil;
- /**
- * 喜钛游 支付
- */
- class XiTaiYouPay
- {
- private $config; // 配置
- private $commonData = [
- 'app_id' => '',
- 'timestamp' => '',
- 'version' => '',
- 'charset' => '',
- 'method' => '',
- 'sign_type' => '',
- ];
- const SIGN_TYPE = "RSA2"; // 签名规则
- const VERSION = "1.0.1";
- const CHARSET = "UTF-8"; // 字符集
- const REQ_URL = "https://api.tengtren.com/"; // 支付请求地址
- const SUCCESS = "SUCCESS";
- const FAIL = "fail";
- private $rsa_helper;
- public function __construct(){
- $this->config = config('xty_pay');
- // dump($this->config['private_file'], $this->config['public_file']);
- $this->rsa_helper = new RSAUtil($this->config['private_file'], $this->config['public_file']);
- }
- /**
- * 初始化公共参数
- * @param string $type 请求类型
- *
- * @return array
- */
- public function initCommonData($type){
- if(!$type){
- return [];
- }
- switch ($type){
- case 'pay_h5':
- $method = 'trade.h5.pay';
- break;
- case 'order_query':
- $method = 'trade.order.query';
- break;
- case 'refund':
- $method = 'trade.order.refund';
- break;
- case 'refund_query':
- $method = 'trade.refund.query';
- break;
- }
- $this->commonData = [
- 'app_id' => $this->config['app_id'],
- 'timestamp' => ParameterUtil::getCurrentDateStr(),
- 'version' => self::VERSION,
- 'charset' => self::CHARSET,
- 'method' => $method,
- 'sign_type' => self::SIGN_TYPE,
- ];
- return $this->commonData;
- }
- // 发起H5支付
- public function payH5($pay_channel, $return_type, $data){
- try {
- $requestData = $this->initCommonData('pay_h5');
- $requestData['req_data'] = [
- "out_trade_no" => $data['out_trade_no'],
- "pay_channel" => $pay_channel, // 支付渠道: WX=微信, ALI=支付宝, UNI=银联
- "order_name" => $data['order_name'],
- "total_amount" => $data['total_amount'], // 金额(分)
- "order_desc" => $data['order_desc'],
- "notify_url" => $data['notify_url'], // 回调地址
- "return_type" => $return_type, // 返回类型: 1=返回跳转支付收银台 URL, 2=返回支付链接, 3=返回官方标准支付 URL, 4=返回支付宝 qrCode
- "return_url" => $data['return_url'], // 前端跳转地址
- // "limit_pay" => "1",
- "payer_client_ip" => $data['ip'],
- // "h5_info" => "{\"type\":\"Android\",\"app_name\": \"XXXXXX\",\"package_name\": \"com.tencent.tmgp.sgame\"}", // 微信H5场景信息
- "reserved" => $data['reserved']??"", // 附加数据
- ];
- $sign = $this->rsa_helper->createRSA2Sign(json_encode($requestData));
- // 请求的为JSON类型的数据
- $result = HttpRequestUtil::sendPost(self::REQ_URL, json_encode($requestData), $sign);
- // $result["responseData"] = {"resp_code":"SUCCESS","resp_data":"{\"order_no\":\"1010371122024090311352084041\",\"biz_code\":\"SUCCESS\",\"pay_data\":\"https://api.tengtren.com/wxH5Pay?orderNo=1010371122024090311352084041&payUrl=weixin%3A%2F%2Fdl%2Fbusiness%2F%3Ft%3DpYe3V25CZ3m&payScene=H5&appId=A17222309452323464&version=1.0.1\"}","resp_msg":"成功","timestamp":"20240903113520"}
- $resp_data_json = json_decode($result["responseData"], TRUE);
- if ("SUCCESS" == $resp_data_json["resp_code"]) {
- if ($this->rsa_helper->verifyRSA2Sign($result["responseData"], $result["signature"])) {
- $newRespData = json_decode($resp_data_json['resp_data'], true);
- if (!empty($newRespData['pay_data'])) {
- return ['code' => 200, 'msg' => "success", 'data' => $newRespData['pay_data']];
- }
- }
- }
- return ['code' => -100, 'msg' => "请求失败: " . $resp_data_json['resp_data'], 'data' => []];
- } catch (\Exception $e) {
- return ['code' => -110, 'msg' => "请求异常:".$e->getMessage(), 'data' => []];
- }
- }
- /**
- * 订单查询
- *
- * @param $order_no string 交易流水号
- * @param $out_trade_no string 商户订单号
- *
- * @return array
- */
- public function orderQuery($out_trade_no, $order_no = '')
- {
- try {
- $request_data = $this->initCommonData('order_query');
- $request_data['req_data'] = [
- "out_trade_no" => $out_trade_no,
- ];
- if(!empty($order_no)){
- $request_data['req_data']['order_no'] = $order_no;
- }
- $sign = $this->rsa_helper->createRSA2Sign(json_encode($request_data));
- // 请求的为JSON类型的数据
- $result = HttpRequestUtil::sendPost(self::REQ_URL, json_encode($request_data), $sign);
- $resp_data_json = json_decode($result["responseData"], TRUE);
- if ("SUCCESS" != $resp_data_json["resp_code"]) {
- return ['code' => -100, 'msg' => "订单查询失败:" . $resp_data_json['resp_data'], 'data' => []];
- }
- if ($this->rsa_helper->verifyRSA2Sign($result["responseData"], $result["signature"]) != true) {
- return ['code' => -101, 'msg' => "订单-签名解析失败: msg=" . $resp_data_json['resp_msg'], 'data' => []];
- }
- $resp_data = json_decode($resp_data_json["resp_data"], TRUE);
- if($resp_data['biz_code'] != "SUCCESS"){
- return ['code' => -103, 'msg' => "订单业务失败状态!", 'data' => []];
- }
- if($resp_data['trade_status'] != "SUCCESS"){
- return ['code' => -104, 'msg' => "订单已关闭或未支付!", 'data' => []];
- }
- return ['code' => 200, 'msg' => "success", 'data' => $resp_data];
- } catch (\Exception $e) {
- return ['code' => -110, 'msg' => "订单查询异常:".$e->getMessage(), 'data' => []];
- }
- }
- // 回调通知
- public function notify($bodyData)
- {
- // 回调验证走查询订单接口验证即可。
- }
- /**
- * 退款
- *
- * @param $out_trade_no
- * @param $out_refund_no
- * @param $refund_amount
- * @param $refund_reason
- *
- * @return array
- */
- public function refund($out_trade_no, $out_refund_no, $refund_amount, $refund_reason)
- {
- try {
- $queryResult = $this->orderQuery($out_trade_no);
- // dump($queryResult);
- if ($queryResult['code'] != 200) {
- return ['code' => -100, 'msg' => $queryResult['msg'], 'data' => []];
- }
- $request_data = $this->initCommonData('refund');
- $request_data['req_data'] = [
- "out_trade_no" => $out_trade_no, // 商户订单号
- // "order_no" => $order_no, // 交易流水号
- "out_refund_no" => $out_refund_no, // 商户退款单号
- "refund_amount" => formatYuanToFen($refund_amount), // 退款金额(分)
- "refund_reason" => $refund_reason, // 退款原因
- ];
- // dump('$request_data: ', $request_data);
- $sign = $this->rsa_helper->createRSA2Sign(json_encode($request_data));
- // 请求的为JSON类型的数据
- $result = HttpRequestUtil::sendPost(self::REQ_URL, json_encode($request_data), $sign);
- $respDataJson = json_decode($result["responseData"], TRUE);
- // dump($respDataJson);
- $respData = "";
- if(!empty($respDataJson)){
- $respData = json_decode($respDataJson['resp_data'], TRUE);
- }
- // dump($respDataJson, $respData, 'xxxxasd');
- /**
- * 退款成功返回样例:
- *
- * array(4) {
- * ["resp_code"]=>string(7) "SUCCESS"
- * ["resp_data"]=>string(313) "{"order_no":"1010317712026012015442715994","refund_ch_order_no":"300220260121000000015829065830","biz_code":"SUCCESS","out_trade_no":"WL17688950675041100742","refund_status":"PROCESSING","out_refund_no":"REF17689609400390212861","total_amount":1,"refund_amount":1,"refund_order_no":"1010417742026012110022036442"}"
- * ["resp_msg"]=>string(6) "成功"
- * ["timestamp"]=>string(14) "20260121100220"
- * }
- *
- * 退款请求失败样例:
- * array(4) {
- * ["resp_code"]=>string(7) "SUCCESS"
- * ["resp_data"]=>
- * string(130) "{"biz_code":"FAIL","error_msg":"请求参数错误:out_trade_no和order_no参数至少一个必填","error_code":"PARAMS_INVALID"}"
- * string(145) "{"biz_code":"FAIL","error_msg":"业务规则检查异常:退款金额不能大于可退金额","refund_status":"FAIL","error_code":"BIZ_INVALID"}"
- * string(149) "{"biz_code":"FAIL","error_msg":"频率限制:同一笔订单多次退款受限,请稍后再试","refund_status":"FAIL","error_code":"RATE_LIMITED"}"
- * ["resp_msg"]=>string(6) "成功"
- * ["timestamp"]=>string(14) "20260121100420"
- * }
- *
- */
- if (!empty($respData) && !empty($respDataJson) && !empty($respData["biz_code"]) && $respData["biz_code"] == "SUCCESS" && ($respData["refund_status"] == "SUCCESS" || $respData["refund_status"] == "PROCESSING")) {
- return ['code' => 200, 'msg' => "success", 'data' => []];
- }
- $errorMsg = $respDataJson['resp_msg'];
- if(!empty($respData['error_msg'])){
- $errorMsg = $respData['error_msg'];
- }
- return ['code' => -100, 'msg' => "退款失败:" . $errorMsg, 'data' => []];
- } catch (\Exception $e) {
- return ['code' => -110, 'msg' => $e->getMessage(), 'data' => []];
- }
- }
- // 退款查询
- public function refund_query($out_refund_no, $refund_order_no){
- try {
- $request_data = $this->initCommonData('refund_query');
- $request_data['req_data'] = [
- "out_refund_no" => $out_refund_no, // 商户退款单号
- "refund_order_no" => $refund_order_no, // 退款交易流水号
- ];
- // dump($request_data);
- $sign = $this->rsa_helper->createRSA2Sign(json_encode($request_data));
- // 请求的为JSON类型的数据
- $result = HttpRequestUtil::sendPost(self::REQ_URL, json_encode($request_data), $sign);
- // dump($result);
- $respDataJson = json_decode($result["responseData"], TRUE);
- $respData = "";
- if(!empty($respDataJson)){
- $respData = json_decode($respDataJson['resp_data'], TRUE);
- }
- // dump($respDataJson, $respData, 'xxxxasd');
- /**
- * 退款成功返回样例:
- *
- * array(4) {
- * ["resp_code"]=>string(7) "SUCCESS"
- * ["resp_data"]=>string(313) "{"order_no":"1010317712026012015442715994","refund_ch_order_no":"300220260121000000015829065830","biz_code":"SUCCESS","out_trade_no":"WL17688950675041100742","refund_status":"PROCESSING","out_refund_no":"REF17689609400390212861","total_amount":1,"refund_amount":1,"refund_order_no":"1010417742026012110022036442"}"
- * ["resp_msg"]=>string(6) "成功"
- * ["timestamp"]=>string(14) "20260121100220"
- * }
- *
- * 退款请求失败样例:
- * array(4) {
- * ["resp_code"]=>string(7) "SUCCESS"
- * ["resp_data"]=>
- * string(130) "{"biz_code":"FAIL","error_msg":"请求参数错误:out_trade_no和order_no参数至少一个必填","error_code":"PARAMS_INVALID"}"
- * string(145) "{"biz_code":"FAIL","error_msg":"业务规则检查异常:退款金额不能大于可退金额","refund_status":"FAIL","error_code":"BIZ_INVALID"}"
- * string(149) "{"biz_code":"FAIL","error_msg":"频率限制:同一笔订单多次退款受限,请稍后再试","refund_status":"FAIL","error_code":"RATE_LIMITED"}"
- * ["resp_msg"]=>string(6) "成功"
- * ["timestamp"]=>string(14) "20260121100420"
- * }
- *
- */
- if (!empty($respData) && !empty($respDataJson) && !empty($respData["biz_code"]) && $respData["biz_code"] == "SUCCESS" && ($respData["refund_status"] == "SUCCESS" || $respData["refund_status"] == "PROCESSING")) {
- return ['code' => 200, 'msg' => "success", 'data' => []];
- }
- $errorMsg = $respDataJson['resp_msg'];
- if(!empty($respData['error_msg'])){
- $errorMsg = $respData['error_msg'];
- }
- return ['code' => -100, 'msg' => "退款失败:" . $errorMsg, 'data' => []];
- } catch (\Exception $e) {
- return ['code' => -110, 'msg' => $e->getMessage(), 'data' => []];
- }
- }
- }
|