# Niushop开源商城通过插件开发新型支付方式
---
支付插件开发是针对3.1以上版本,实现统一化的支付功能进行设置的。
下面以微信支付的开发进行说明
![](https://img.kancloud.cn/90/ca/90ca77d967d0f4c3ace60c83fa3ac766_445x153.png)
* **后台菜单功能开发:**
主要实现后台微信支付的配置界面,具体的配置以及代码书写可以参照插件后台功能开发细节![](https://img.kancloud.cn/fd/7b/fd7be20b01e9b83eb59e61ca7abe2e23_1122x681.png)
* **实现钩子开发 1. 获取支付配置 payconfig\($param\)**
该钩子主要在查询当前存在的支付方式,以及实际支付调用时进行查询。
![](https://img.kancloud.cn/8f/1f/8f1f770f31bda863ae4c624fb16e1baa_1363x447.png)
* **实现钩子开发 2. 支付**
不同的支付方式实际支付返回的数据不同,比如扫码支付返回的是二维码路径,jsapi支付可能直接就调用了,通过调用网址方式返回url,直接打开方式返回html等等,所以系统设置了几种可能返回的形式,方便处理,下面是pay控制器下面
```php
//返回形式 code_url, url , 直接跳转
$result = hook("pay", [ 'addon_name' => $type, 'out_trade_no' => $out_trade_no, 'notify_url' => $notify_url, 'return_url' => $return_url ]);
$result = arrayFilter($result);
$result = $result[0];
if ($result['data']['return_type'] == 'qrcode') {
$path = getQRcode($result['data']['code_url'], "upload/qrcode/pay", $out_trade_no);
$this->assign("path", __ROOT__ . '/' . $path);
$pay_result = api('System.Pay.payInfo', [ 'out_trade_no' => $out_trade_no ]);
$pay_value = $pay_result["data"];
$this->assign('pay_value', $pay_value);
return $this->view($this->style . "pay/qrcode");
} elseif ($result['data']['return_type'] == 'url') {
if ($result['code'] > 0) {
$this->redirect($result["url"]);
} else {
$this->error($result['data']['out_message']);
}
} elseif ($result['data']['return_type'] == 'html') {
echo $result['data']['html'];
}
```
微信支付书写方案
```php
$pay_service = new Pay();
if (!isWeixin()) {
// 扫码支付
if (request()->isMobile()) {
$res = $pay_service->wchatPay($param['out_trade_no'], 'MWEB', $param['notify_url']);
if (empty($res['mweb_url']))
{
return error(['return_type' => 'url', 'out_message' => json_encode($res, JSON_UNESCAPED_UNICODE)]);
}
return success(['return_type' => 'url', 'url' => $res["mweb_url"]]);
} else {
$res = $pay_service->wchatPay($param['out_trade_no'], 'NATIVE', $param['notify_url']);
if ($res["return_code"] == "SUCCESS") {
if (empty($res['code_url'])) {
$code_url = json_encode($res, JSON_UNESCAPED_UNICODE);
} else {
$code_url = $res['code_url'];
}
if (!empty($res["err_code"]) && $res["err_code"] == "ORDERPAID" && $res["err_code_des"] == "该订单已支付") {
$code_url = json_encode($res, JSON_UNESCAPED_UNICODE);;
}
} else {
$code_url = json_encode($res, JSON_UNESCAPED_UNICODE);
}
return success(['return_type' => 'qrcode', 'code_url' => $code_url]);
}
} else {
// jsapi支付
$res = $pay_service->wchatPay($param['out_trade_no'], 'JSAPI', $param['notify_url']);
if (!empty($res["return_code"]) && $res["return_code"] == "FAIL" && $res["return_msg"] == "JSAPI支付必须传openid") {
return error(['return_type' => 'url', 'out_message' => json_encode($res, JSON_UNESCAPED_UNICODE)]);
} else {
$retval = $pay_service->getWxJsApi($res);
$this->assign("out_trade_no", $param['out_trade_no']);
$this->assign('jsApiParameters', $retval);
$view = $this->fetch(ADDON_DIR . '/NsWeixinpay/template/wechat_pay.html');
return success(['return_type' => 'html', 'html' => $view]);
}
}
```
1. jsapi支付,直接进入微信内部,支付成功之后微信回调,然后返回支付结构,系统自动按照返回结果展示。
2. h5支付,调用微信付接口,返回接口url,系统调用url
3. 扫码支付返回二维码url,系统通过扫码url执行扫描。
* **支付异步回调 payNotify**
每种支付实现对应异步回调,微信支付异步执行,实现异步回调。
* **支付退款 refund\($param\)**
执行对应支付订单的退款操作,实现支付退款接口。
* **支付转账 transfer\($param\)**
实现支付转账接口业务。