formPayTrait.php 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. <?php
  2. namespace App\Admin\Controllers\Traits\WxSettingTraits;
  3. use App\Lib\WeApp\WeApp;
  4. use App\Wen\Utils\SiteUtils;
  5. use Yansongda\Pay\Pay;
  6. use App\Wen\Utils\GatewayUtils;
  7. use App\Wen\Utils\Settings;
  8. use Dcat\Admin\Layout\Content;
  9. use Dcat\Admin\Widgets\Form;
  10. use Illuminate\Http\Request;
  11. use Illuminate\Support\Facades\Cache;
  12. trait formPayTrait{
  13. public function index_pay(Content $content)
  14. {
  15. return $content->title('支付配置')
  16. // ->body($this->buildPreviewButton())
  17. // ->body($this->newline())
  18. ->body(
  19. <<<HTML
  20. <div class="card">{$this->form_pay()->render()}</div>
  21. HTML
  22. );
  23. }
  24. protected function form_pay(){
  25. $form = new Form();
  26. $form->confirm('您确定要提交表单吗?', 'content');
  27. $form->disableResetButton();
  28. $form->tab('开关', function (Form $form) {
  29. $form->html(function () {
  30. return '<div style="background-color: powderblue; color: #414750; padding: 10px;">提示: 小程序内必须使用小程序支付,所以不用选择。</div>';
  31. }, '');
  32. $form->radio('app_app_pay_type_wechat', '微信')->help('App内微信的支付方式')->options(['close' => '关闭', 'app'=>'app', 'h5'=>'h5', 'yi'=>'yi'])->default(Settings::get('app_app_pay_type_wechat', 'app'));
  33. $form->radio('app_app_pay_type_ali', '支付宝')->help('App内支付宝的支付方式')->options(['close' => '关闭', 'app'=>'app', 'h5'=>'h5', 'yi'=>'yi'])->default(Settings::get('app_app_pay_type_ali', 'app'));
  34. $form->radio('app_app_pay_type_apple', '苹果内购')->help('IOS是否开启苹果内购,若开启了审核模式,则会强制开启')->options(['close' => '关闭', 'open'=>'开启'])->default(Settings::get('app_app_pay_type_apple', 'close'));
  35. $form->divider();
  36. $form->html(function () {
  37. return '<div style="background-color: powderblue; color: #414750; padding: 10px;">提示: ios系统微信小程序不允许虚拟产品的购买,所以你可以设置是否采用公众号支付来替代。</div>';
  38. }, '');
  39. $form->switch('mini_ios_virtual_products_mp_pay', '虚拟产品开启公众号支付')->help('需要你配置好公众号的服务器链接[全局配置-支付-微信-公众号],且配置好h5端的域名[全局配置-常规-h5端]')->default(Settings::get('mini_ios_virtual_products_mp_pay', 0));
  40. });
  41. $form->tab('微信', function (Form $form) {
  42. $form->html(function () {
  43. return '';
  44. }, '<b style="color: #605ab0;">一、微信小程序</b>');
  45. $form->text('app_id', 'AppID')->help('前往:https://mp.weixin.qq.com/')->default(Settings::get('app_id', ''));
  46. $form->text('app_meta_appid', '原始ID')->help('前往:https://mp.weixin.qq.com/,注意这个是原始ID,类似:gh_31aec555bf2f,这个不填,分享到微信聊天则使用普通图文分享,如果这里配置了,则使用小程序专属分享,<a href="https://img.mini.minisns.cn/images/meta_appid.jpg" target="_blank">点击查看查找位置</a>')->default(Settings::get('app_meta_appid', ''));
  47. $form->password('app_secret', 'AppSecret')->help('前往:https://mp.weixin.qq.com/')->default(Settings::get('app_secret', ''));
  48. $form->html(function () {
  49. return '<div style="background-color: transparent;color: #414750;padding: 10px;border-radius: 5px;display: inline-block"><b style="color: red;">*</b> <span style="color: #605ab0;font-weight: bold;">小程序</span> 消息推送: 服务器地址: <b>'.env('APP_URL').'/api/v1/wechat/mini/event</b><br/><a href="https://img.mini.minisns.cn/images/mini_message_event_url_tip2.png" target="_blank">查看配置示例教程</a></div>';
  50. }, '');
  51. $form->text('app_message_token', 'Token')->default(Settings::get('app_message_token', ''));
  52. $form->text('app_message_aes_key', 'EncodingAESKey')->default(Settings::get('app_message_aes_key', ''));
  53. $form->switch('need_mini_deliver_info_manage', '对接《发货信息管理》')->default(Settings::get('need_mini_deliver_info_manage', 0));
  54. $form->divider();
  55. $form->html(function () {
  56. return '';
  57. }, '<b style="color: #2ba245;">二、公众号</b>');
  58. $form->text('mp_app_id', 'AppID')->help('前往:https://mp.weixin.qq.com/')->default(Settings::get('mp_app_id', ''));
  59. $form->password('mp_app_secret', 'AppSecret')->help('前往:https://mp.weixin.qq.com/')->default(Settings::get('mp_app_secret', ''));
  60. $form->text('mp_app_name', '公众号名称')->default(Settings::get('mp_app_name', ''));
  61. $form->html(function () {
  62. return '<div style="background-color: transparent;color: #414750;padding: 10px;border-radius: 5px;display: inline-block"><b style="color: red;">*</b> <span style="color: #2ba245;font-weight: bold;">公众号</span> 消息推送:服务器地址: <b>'.env('APP_URL').'/api/v1/wechat/mp/event</b><br/><a href="https://img.mini.minisns.cn/images/mp_url_tip2.png" target="_blank">查看配置示例教程</a></div>';
  63. }, '');
  64. $form->text('mp_app_token', 'Token')->default(Settings::get('mp_app_token', ''));
  65. $form->text('mp_app_aes_key', 'EncodingAESKey')->default(Settings::get('mp_app_aes_key', ''));
  66. $form->divider();
  67. $form->html(function () {
  68. return '';
  69. }, '<b>三、App移动应用</b>');
  70. $form->html(function () {
  71. return '<div style="background-color: powderblue;color: #414750;padding: 10px;border-radius: 5px;display: inline-block">应用签名教程: <a href="https://doc.minisns.cn/doc/141/" target="_blank">https://doc.minisns.cn/doc/141/</a></div>';
  72. }, '');
  73. $form->text('app_app_id', 'AppID')->help('前往:https://open.weixin.qq.com/')->default(Settings::get('app_app_id', ''));
  74. $form->password('app_app_secret', 'AppSecret')->help('前往:https://open.weixin.qq.com/')->default(Settings::get('app_app_secret', ''));
  75. $form->divider();
  76. $form->html(function () {
  77. return '';
  78. }, '<b>四、网站应用</b>');
  79. $form->text('web_app_id', 'AppID')->help('前往:https://open.weixin.qq.com/')->default(Settings::get('web_app_id', ''));
  80. $form->password('web_app_secret', 'AppSecret')->help('前往:https://open.weixin.qq.com/')->default(Settings::get('web_app_secret', ''));
  81. $form->divider();
  82. $form->html(function () {
  83. return '';
  84. }, '<b>五、微信商户</b>');
  85. $form->text('mch_id', '商户号')->help('前往:https://pay.weixin.qq.com/')->default(Settings::get('mch_id', ''));
  86. $form->password('mch_secret', '商户密钥')->help('区别于私钥,一字之隔,自己在微信商家后台自定义的32位。前往:https://pay.weixin.qq.com/,请把v2版本和v3版本都设置且保持一致,新版本已更换为v3接口')->default(Settings::get('mch_secret', ''));
  87. $form->textarea('mch_cert_client', '商户公钥')->help('<b>必选</b>,可在 账户中心->API安全->申请API证书 里获得(apiclient_cert.pem)')->default(Settings::get('mch_cert_client', ''));
  88. $form->textarea('mch_cert_key', '商户私钥')->help('<b>必选</b>,账户中心->API安全->申请API证书 里获得(apiclient_key.pem)')->default(Settings::get('mch_cert_key', ''));
  89. $form->switch('mch_transfer_to_weChat', '《商家转账到零钱》')->help('产品是否开通')->default(Settings::get('mch_transfer_to_weChat', 0));
  90. });
  91. $form->tab('支付宝', function (Form $form) {
  92. $form->text('ali_app_id', 'AppID')->help('前往:<a href="https://open.alipay.com/" target="_blank">https://open.alipay.com/</a>')->default(Settings::get('ali_app_id', null));
  93. $form->html(function () {
  94. return '<div style="background-color: powderblue;color: #414750;padding: 10px;border-radius: 5px;">1、首先你自己通过<a href="https://docs.open.alipay.com/291/105971" target="_blank" style="color:#f00;text-decoration:underline;">RSA签名验签工具</a>,以<span style="color:#f00">证书</span>的方式,生成一个公钥和私钥,私钥需要经过处理成PKCS1格式填到下面,公钥不用填</div>';
  95. }, '');
  96. $form->textarea('ali_private_key', '应用私钥')->help('<a href="https://img.mini.minisns.cn/hbx/pkcs.jpg" target="_blank">处理成PKCS1格式教程</a>')->default(Settings::get('ali_private_key', ''));
  97. $form->html(function () {
  98. return '<div style="background-color: powderblue;color: #414750;padding: 10px;border-radius: 5px;">2、然后把生成的<b>csr文件</b>填在支付宝后台可以获得支付宝公钥等<span style="color:#f00">三个证书</span>,将证书以“记事本”打开,复制里面的内容到对应的框框里</div>';
  99. }, '');
  100. $form->textarea('ali_my_publish_key', '应用公钥')->help('<a href="https://img.mini.minisns.cn/hbx/alipay_tip.png" target="_blank">三个证书说明</a>')->default(Settings::get('ali_my_publish_key', ''));
  101. $form->textarea('ali_public_key', '支付宝公钥')->default(Settings::get('ali_public_key', null));
  102. $form->textarea('ali_root_key', '支付宝根证书')->default(Settings::get('ali_root_key', null));
  103. $form->switch('ali_transfer_to_rest', '《转账到支付宝账户》')->help('产品是否开通')->default(Settings::get('ali_transfer_to_rest', 0));
  104. });
  105. $form->tab('苹果', function (Form $form) {
  106. $form->text('apple_pay_password', 'App共享密码')->help('<a href="https://img.mini.minisns.cn/images/apple_pay_password.jpg" target="_blank">点击查看</a>')->placeholder('4bd0b352aef2445ae34a895468c1747f')->default(Settings::get('apple_pay_password', ''));
  107. });
  108. $form->tab('易支付', function (Form $form) {
  109. $form->text('yi_app_id', '商户ID')->help('前往:<a href="https://pay.minisns.cn/" target="_blank">https://pay.minisns.cn/</a>,<a href="https://img.mini.minisns.cn/images/pay/pay_tip.jpg" target="_blank">查看教程</a>')->default(Settings::get('yi_app_id', null));
  110. $form->text('yi_app_secret', '商户密钥')->default(Settings::get('yi_app_secret', null));
  111. $form->text('yi_provider_url', '接口api')->default(Settings::get('yi_provider_url', 'https://pay.minisns.cn'));
  112. });
  113. $form->action('settings/action/pay');
  114. return $form;
  115. }
  116. public function pay(Request $request){
  117. if($request->input('need_mini_deliver_info_manage', 0) == 1){
  118. $weapp = new WeApp('mini');
  119. $manage = $weapp->getDeliverInfoManage();
  120. if(!$manage->isNeed()){
  121. return $this->response()->error('你的小程序无需开启《发货信息管理》!');
  122. }
  123. }
  124. SiteUtils::forget_config_data();
  125. Settings::set('app_app_pay_type_wechat', $request->input('app_app_pay_type_wechat'), true);
  126. Settings::set('app_app_pay_type_ali', $request->input('app_app_pay_type_ali'), true);
  127. Settings::set('app_app_pay_type_apple', $request->input('app_app_pay_type_apple'), true);
  128. Settings::set('mini_ios_virtual_products_mp_pay', $request->input('mini_ios_virtual_products_mp_pay') == 1 ? 1 : 0, true);
  129. Settings::set('app_id', $request->input('app_id'), true);
  130. Settings::set('app_meta_appid', $request->input('app_meta_appid'), true);
  131. Settings::set('app_secret', $request->input('app_secret'));
  132. Settings::set('mp_app_id', $request->input('mp_app_id'), true);
  133. Settings::set('mp_app_secret', $request->input('mp_app_secret'));
  134. Settings::set('mp_app_name', $request->input('mp_app_name'));
  135. Settings::set('mp_app_token', $request->input('mp_app_token'));
  136. Settings::set('mp_app_aes_key', $request->input('mp_app_aes_key'));
  137. Settings::set('app_message_token', $request->input('app_message_token'));
  138. Settings::set('app_message_aes_key', $request->input('app_message_aes_key'));
  139. Settings::set('web_app_id', $request->input('web_app_id'), true);
  140. Settings::set('web_app_secret', $request->input('web_app_secret'));
  141. Settings::set('app_app_id', $request->input('app_app_id'), true);
  142. Settings::set('app_app_secret', $request->input('app_app_secret'));
  143. Settings::set('mch_id', $request->input('mch_id'), true);
  144. Settings::set('mch_secret', $request->input('mch_secret'));
  145. Settings::set('mch_cert_client', $request->input('mch_cert_client'));
  146. Settings::set('mch_cert_key', $request->input('mch_cert_key'));
  147. Settings::set('mch_transfer_to_weChat', $request->input('mch_transfer_to_weChat', 0) == 1 ? 1 : 0, true);
  148. Settings::set('need_mini_deliver_info_manage', $request->input('need_mini_deliver_info_manage', 0) == 1 ? 1 : 0, true);
  149. //支付宝
  150. Settings::set('ali_app_id', $request->input('ali_app_id'), true);
  151. Settings::set('ali_public_key', $request->input('ali_public_key'), true);
  152. Settings::set('ali_root_key', $request->input('ali_root_key'), true);
  153. Settings::set('ali_transfer_to_rest', $request->input('ali_transfer_to_rest') == 1 ? 1 : 0, true);
  154. Settings::set('ali_private_key', $request->input('ali_private_key'));
  155. Settings::set('ali_my_publish_key', $request->input('ali_my_publish_key'));
  156. Settings::set('apple_pay_password', $request->input('apple_pay_password'), true);
  157. //易支付
  158. Settings::set('yi_app_id', $request->input('yi_app_id'), true);
  159. Settings::set('yi_app_secret', $request->input('yi_app_secret'));
  160. Settings::set('yi_provider_url', $request->input('yi_provider_url'), true);
  161. $yi_pay_config = [
  162. 'app_id' => $request->input('yi_app_id'),
  163. 'app_secret' => $request->input('yi_app_secret'),
  164. 'provider_url'=> $request->input('yi_provider_url'),
  165. 'site' => Settings::get('app_title'),
  166. 'notify_url' => env('APP_URL'). '/api/v1/app/yi/notify',
  167. 'return_url' => env('APP_URL')
  168. ];
  169. Cache::forget('yi_pay_config');
  170. Cache::put('yi_pay_config', json_encode($yi_pay_config));
  171. $app_pay_config = [
  172. 'alipay' => [
  173. 'default' => [
  174. // 必填-支付宝分配的 app_id
  175. 'app_id' => $request->input('ali_app_id'),
  176. // 必填-应用私钥 字符串或路径
  177. // 在 https://open.alipay.com/develop/manage 《应用详情->开发设置->接口加签方式》中设置
  178. 'app_secret_cert' => $request->input('ali_private_key', ''),
  179. // 必填-应用公钥证书 路径
  180. // 设置应用私钥后,即可下载得到以下3个证书
  181. 'app_public_cert_path' => storage_path('app/certs/alipay/appCertPublicKey.crt'),
  182. // 必填-支付宝公钥证书 路径
  183. 'alipay_public_cert_path' => storage_path('app/certs/alipay/alipayCertPublicKey_RSA2.crt'),
  184. // 必填-支付宝根证书 路径
  185. 'alipay_root_cert_path' => storage_path('app/certs/alipay/alipayRootCert.crt'),
  186. 'return_url' => env('APP_URL'),
  187. 'notify_url' => env('APP_URL'). '/api/v1/app/ali/notify/app',
  188. // 选填-第三方应用授权token
  189. 'app_auth_token' => '',
  190. // 选填-服务商模式下的服务商 id,当 mode 为 Pay::MODE_SERVICE 时使用该参数
  191. 'service_provider_id' => '',
  192. // 选填-默认为正常模式。可选为: MODE_NORMAL, MODE_SANDBOX, MODE_SERVICE
  193. 'mode' => Pay::MODE_NORMAL,
  194. ]
  195. ],
  196. 'wechat' => [
  197. 'default' => [
  198. // 必填-商户号,服务商模式下为服务商商户号
  199. // 可在 https://pay.weixin.qq.com/ 账户中心->商户信息 查看
  200. 'mch_id' => $request->input('mch_id'),
  201. // 选填-v2商户私钥
  202. 'mch_secret_key_v2' => $request->input('mch_secret', ''),
  203. // 必填-v3 商户秘钥
  204. // 即 API v3 密钥(32字节,形如md5值),可在 账户中心->API安全 中设置
  205. 'mch_secret_key' => $request->input('mch_secret', ''),
  206. // 必填-商户私钥 字符串或路径
  207. // 即 API证书 PRIVATE KEY,可在 账户中心->API安全->申请API证书 里获得
  208. // 文件名形如:apiclient_key.pem
  209. 'mch_secret_cert' => storage_path('app/certs/wechat/apiclient_key.pem'),
  210. // 必填-商户公钥证书路径
  211. // 即 API证书 CERTIFICATE,可在 账户中心->API安全->申请API证书 里获得
  212. // 文件名形如:apiclient_cert.pem
  213. 'mch_public_cert_path' => storage_path('app/certs/wechat/apiclient_cert.pem'),
  214. // 必填-微信回调url
  215. // 不能有参数,如?号,空格等,否则会无法正确回调
  216. 'notify_url' => env('APP_URL'). '/api/v1/app/wechat/notify',
  217. // 选填-公众号 的 app_id
  218. // 可在 mp.weixin.qq.com 设置与开发->基本配置->开发者ID(AppID) 查看
  219. 'mp_app_id' => $request->input('mp_app_id', ''),
  220. // 选填-小程序 的 app_id
  221. 'mini_app_id' => $request->input('app_id', ''),
  222. // 选填-app 的 app_id
  223. 'app_id' => $request->input('app_app_id', ''),
  224. // 选填-合单 app_id
  225. 'combine_app_id' => '',
  226. // 选填-合单商户号
  227. 'combine_mch_id' => '',
  228. // 选填-服务商模式下,子公众号 的 app_id
  229. 'sub_mp_app_id' => '',
  230. // 选填-服务商模式下,子 app 的 app_id
  231. 'sub_app_id' => '',
  232. // 选填-服务商模式下,子小程序 的 app_id
  233. 'sub_mini_app_id' => '',
  234. // 选填-服务商模式下,子商户id
  235. 'sub_mch_id' => '',
  236. // 选填-微信平台公钥证书路径, optional,强烈建议 php-fpm 模式下配置此参数
  237. 'wechat_public_cert_path' => [
  238. // '45F59D4DABF31918AFCEC556D5D2C6E376675D57' => __DIR__.'/Cert/wechatPublicKey.crt',
  239. ],
  240. // 选填-默认为正常模式。可选为: MODE_NORMAL, MODE_SERVICE
  241. 'mode' => Pay::MODE_NORMAL,
  242. ]
  243. ],
  244. 'unipay' => [
  245. 'default' => [
  246. // 必填-商户号
  247. 'mch_id' => '777290058167151',
  248. // 必填-商户公私钥
  249. 'mch_cert_path' => __DIR__.'/Cert/unipayAppCert.pfx',
  250. // 必填-商户公私钥密码
  251. 'mch_cert_password' => '000000',
  252. // 必填-银联公钥证书路径
  253. 'unipay_public_cert_path' => __DIR__.'/Cert/unipayCertPublicKey.cer',
  254. // 必填
  255. 'return_url' => 'https://yansongda.cn/unipay/return',
  256. // 必填
  257. 'notify_url' => 'https://yansongda.cn/unipay/notify',
  258. ],
  259. ],
  260. 'logger' => [
  261. 'enable' => true,
  262. 'file' => storage_path('logs/pay.log'),
  263. 'level' => 'info', // 建议生产环境等级调整为 info,开发环境为 debug
  264. 'type' => 'daily', // optional, 可选 daily.
  265. 'max_file' => 5, // optional, 当 type 为 daily 时有效,默认 30 天
  266. ],
  267. 'http' => [ // optional
  268. 'timeout' => 5.0,
  269. 'connect_timeout' => 5.0,
  270. // 更多配置项请参考 [Guzzle](https://guzzle-cn.readthedocs.io/zh_CN/latest/request-options.html)
  271. ],
  272. ];
  273. Cache::forget('app_pay_config');
  274. Cache::put('app_pay_config', json_encode($app_pay_config));
  275. _update_env([
  276. "WECHATSERVICEACCOUNT_CLIENT_ID" => $request->input('mp_app_id', ''),
  277. "WECHATSERVICEACCOUNT_CLIENT_SECRET" => $request->input('mp_app_secret'),
  278. "WEIXIN_KEY" => $request->input('app_app_id', ''),
  279. "WEIXIN_SECRET" => $request->input('app_app_secret', ''),
  280. ]);
  281. $f1 = fopen(storage_path('app/certs/wechat/apiclient_key.pem'), 'w');
  282. fwrite($f1, $request->input('mch_cert_key', ''));
  283. fclose($f1);
  284. $f2 = fopen(storage_path('app/certs/wechat/apiclient_cert.pem'), 'w');
  285. fwrite($f2, $request->input('mch_cert_client', ''));
  286. fclose($f2);
  287. $f3 = fopen(storage_path('app/certs/alipay/appCertPublicKey.crt'), 'w');
  288. fwrite($f3, $request->input('ali_my_publish_key', ''));
  289. fclose($f3);
  290. $f4 = fopen(storage_path('app/certs/alipay/alipayRootCert.crt'), 'w');
  291. fwrite($f4, $request->input('ali_root_key', ''));
  292. fclose($f4);
  293. $f5 = fopen(storage_path('app/certs/alipay/alipayCertPublicKey_RSA2.crt'), 'w');
  294. fwrite($f5, $request->input('ali_public_key', ''));
  295. fclose($f5);
  296. $__global_config_version__ = Settings::get('__global_config_version__', 1) + 1;
  297. Settings::set('__global_config_version__', $__global_config_version__);
  298. GatewayUtils::success('all', 13, [ 'version' => $__global_config_version__, 'file' => basename(__FILE__) ]);
  299. return $this->response()->success('成功!');
  300. }
  301. }