汇旺财支付PHP代码
下面是调起支付
<?php
namespace app\api\controller;
use app\admin\model\business\Order as VipOrder;
use app\common\controller\Api;
use app\common\model\ShopOrder;
use EasyWeChat\Factory;
use think\Config;
class Hstypay extends Api
{
protected $noNeedLogin = [''];
protected $noNeedRight = ['*'];
public function _initialize()
{
parent::_initialize();
// 这里的配置信息可以写入基本配置里面,这里只是为了练手
$this->config = [
'app_id' => Config::get('site.app_id'),
'secret' => Config::get('site.secret'),
// 下面为可选项
// 指定 API 调用返回结果的类型:array(default)/collection/object/raw/自定义类名
'response_type' => 'array',
'log' => [
'level' => 'debug',
'file' => ROOT_PATH . '/public/logs/wxMiniProgramLogin.log'
]
];
$this->app = Factory::miniProgram($this->config);
}
/**
* 商城订单
* @return void
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function shop_pay(){
$order_id = $this->request->post('order_id');
if(empty($order_id)){
$this->error('参数错误');
}
$order_info = ShopOrder::where('id',$order_id)
->where('user_id',$this->auth->id)
->where('status','1')
->find();
if(empty($order_info)){
$this->error('订单不存在或不是待支付状态');
}
//登录获取openid 这里是用前端的code获取
$code = $this->request->post('code');
if (!$code) {
$this->error('缺少必要参数code');
}
$result = $this->app->auth->session($code);
if (!$result) {
$this->error('获取sessionKey和openId时异常');
}
if (!empty($result['errcode']) && $result['errcode'] != 0) {
$this->error('登录失败',['code' => $result['errcode'], 'msg' => $result['errmsg']]);
}
$openid = $result['openid'];
if ($order_info['status'] != 1){
$this->error("该订单已支付不可重复支付");
}
$this->payGateway($order_info['order_num'],$order_info->amount*100,'订单支付',$openid,'shop_pay');
}
/**
* 旺财支付
* @param $order_num //订单号
* @param $price //支付金额单位分
* @param $body //订单描述
* @param $openid //微信小程序openid
* @param $type //用于区分跳转到不同的回调
* @return void
*/
public function payGateway($order_num,$price,$body,$openid,$type){
$price = intval($price);
$data['service'] = 'pay.weixin.jspay';
$data['sign_type'] = 'MD5';
$data['mch_id'] = Config::get('site.hui_mch_id');
$data['is_raw'] = '1';
$data['is_minipg'] = '1';
//订单号
$data['out_trade_no'] = $order_num;
//商品描述
$data['body'] = $body;
//小程序用户openid
$data['sub_openid'] = $openid;
//小程序appid
$data['sub_appid'] = Config::get('site.app_id');
//支付金额 单位分
$data['total_fee'] = $price;
//本服务器的ip
$data['mch_create_ip'] = $_SERVER['SERVER_ADDR'];
//异步通知地址
$data['notify_url'] = request()->domain()."/api/hstynotify/".$type;//shop_pay商城订单 vip_pay VIP订单 recharge_pay余额重置
//随机字符串
$data['nonce_str'] = \fast\Random::alpha(15);
//签名
$data['sign'] = hstySign($data);
$url = 'https://pay.hstypay.com/v2/pay/gateway';
// 发送post请求
$xmlData = arrayToXml($data);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xmlData); // 发送 XML 数据
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: text/xml', // 设置请求头为 XML
]);
$result = curl_exec($ch);
if (curl_errno($ch)) {
// 请求失败
echo 'Curl error: ' . curl_error($ch);
} else {
// 请求成功
// 请求成功,将返回的 XML 转换为数组
$responseArray = xmlToArray($result);
$pay_info = json_decode($responseArray['pay_info']);
$this->success('成功',$pay_info);
}
}
}
回调代码
<?php
namespace app\api\controller;
use addons\epay\library\Service;
use app\admin\model\business\Man;
use app\admin\model\business\Order as VipOrder;
use app\common\controller\Api;
use app\common\model\ShopOrder;
use app\common\model\User;
use think\Log;
class Hstynotify extends Api
{
protected $noNeedLogin = '*';
protected $noNeedRight = '*';
/**
* 商城订单回调
* @return \Psr\Http\Message\ResponseInterface|string|\Symfony\Component\HttpFoundation\Response|\think\response\Json
* @throws \Yansongda\Pay\Exception\ContainerException
* @throws \Yansongda\Pay\Exception\InvalidParamsException
* @throws \Yansongda\Pay\Exceptions\InvalidArgumentException
* @throws \Yansongda\Pay\Exceptions\InvalidConfigException
* @throws \Yansongda\Pay\Exceptions\InvalidSignException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function shop_pay(){
$post = file_get_contents('php://input');
// \think\Log::record("旺财回调shop_pay成功,XML:".$post);
$post = xmlToArray($post);
if(isset($post['status']) && $post['status']==0 &&isset($post['result_code']) && $post['result_code']==0){
$sign = $post['sign'];
unset($post['sign']);
if(strtolower($sign) != hstySign($post)){
echo 'fail';
exit();
}
// \think\Log::record("旺财回调成功recharge_pay,验签成功");
//你可以在此编写订单逻辑
$order_info = ShopOrder::where('order_num',$post['out_trade_no'])->find();
if($order_info->status != 1){
echo 'success';
exit();
}
$order_info->pay_type = '1';
$order_info->status = '2';
$order_info->pay_order_num = $post['transaction_id'];
$order_info->pay_time = time();
$order_info->save();
echo 'success';
exit();
}else{
echo 'fail';
exit();
}
}
}
签名及XML转换公共方法
/**
* 旺财支付签名
* @param $data
* @return string
*/
function hstySign($data){
//md5 签名字符串,后台获取
$md5_key = \think\Config::get('site.hui_md5');
$str = '';
ksort($data);
foreach ($data as $key=>$value){
if(empty($str)){
$str = $str.$key.'='.$value;
}else{
$str = $str.'&'.$key.'='.$value;
}
}
$sign = strtolower(md5($str.'&key='.$md5_key));
return $sign;
}
// 将数组转换为 XML
function arrayToXml($data) {
$xml = '<xml>';
foreach ($data as $key => $val) {
if (is_numeric($val)) {
$xml .= "<{$key}>{$val}</{$key}>";
} else {
$xml .= "<{$key}><![CDATA[{$val}]]></{$key}>";
}
}
$xml .= '</xml>';
return $xml;
}
/**
* 将 XML 转换为数组
* @param string $xml XML 字符串
* @return array 转换后的数组
*/
function xmlToArray($xml) {
// 将 XML 字符串转换为 SimpleXMLElement 对象
$xmlObject = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA);
// 将对象转换为 JSON 字符串
$json = json_encode($xmlObject);
// 将 JSON 字符串转换为数组
return json_decode($json, true);
}
退款代码
$data['service'] = 'unified.trade.refund';//退款
$data['sign_type'] = 'MD5';
$data['mch_id'] = Config::get('site.hui_mch_id');//商家编号
$data['out_trade_no'] = $order_info->order_num;//订单号
$data['out_refund_no'] = $order_info->id.time();//退款单号
$data['total_fee'] = $order_info->amount*100;//订单总金额
$data['refund_fee'] = $order_info->amount*100;//退款金额
$data['op_user_id'] = Config::get('site.hui_mch_id');//固定传参
//随机字符串
$data['nonce_str'] = \fast\Random::alpha(15);
//签名
$data['sign'] = hstySign($data);
$url = 'https://pay.hstypay.com/v2/pay/gateway';
// 发送post请求
$xmlData = arrayToXml($data);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xmlData); // 发送 XML 数据
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: text/xml', // 设置请求头为 XML
]);
$result = curl_exec($ch);
if (curl_errno($ch)) {
// 请求失败
$this->error('调用汇旺财支付退款接口失败');
} else {
// 请求成功,将返回的 XML 转换为数组
$responseArray = xmlToArray($result);
if($responseArray['status'] != 0){
$this->error('调用汇旺财支付退款接口失败');
}
}
官方文档https://open.swiftpass.cn/openapi/doc?index_1=138&index_2=35&chapter_1=1884&chapter_2=1885