Pay.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. <?php
  2. namespace common\components;
  3. use Yii;
  4. use yii\base\Component;
  5. use common\components\payment\AliPay;
  6. use common\components\payment\UniPay;
  7. use common\components\payment\WechatPay;
  8. use common\components\payment\ByteDancePay;
  9. use common\components\payment\Stripe;
  10. use common\helpers\ArrayHelper;
  11. /**
  12. * 支付组件
  13. *
  14. * Class Pay
  15. * @package common\components
  16. * @property \common\components\payment\WechatPay $wechat
  17. * @property \common\components\payment\AliPay $alipay
  18. * @property \common\components\payment\UniPay $unipay
  19. * @property \common\components\payment\ByteDancePay $byteDance
  20. * @property \common\components\payment\Stripe $stripe
  21. * @author jianyan74 <751393839@qq.com>
  22. */
  23. class Pay extends Component
  24. {
  25. /**
  26. * 默认配置
  27. *
  28. * @var array
  29. */
  30. protected $config = [
  31. 'alipay' => [
  32. 'default' => [
  33. // 必填-支付宝分配的 app_id
  34. 'app_id' => '',
  35. // 必填-应用私钥 字符串或路径
  36. 'app_secret_cert' => '',
  37. // 必填-应用公钥证书 路径
  38. 'app_public_cert_path' => '', // /Users/yansongda/pay/cert/appCertPublicKey_2016082000295641.crt
  39. // 必填-支付宝公钥证书 路径
  40. 'alipay_public_cert_path' => '', // /Users/yansongda/pay/cert/alipayCertPublicKey_RSA2.crt
  41. // 必填-支付宝根证书 路径
  42. 'alipay_root_cert_path' => '', // /Users/yansongda/pay/cert/alipayRootCert.crt
  43. 'return_url' => '', // https://yansongda.cn/alipay/return
  44. 'notify_url' => '', // https://yansongda.cn/alipay/notify
  45. // 选填-第三方应用授权token
  46. 'app_auth_token' => '',
  47. // 选填-服务商模式下的服务商 id,当 mode 为 Pay::MODE_SERVICE 时使用该参数
  48. 'service_provider_id' => '',
  49. // 选填-默认为正常模式。可选为: MODE_NORMAL, MODE_SANDBOX, MODE_SERVICE
  50. 'mode' => \Yansongda\Pay\Pay::MODE_NORMAL,
  51. ]
  52. ],
  53. 'wechat' => [
  54. 'default' => [
  55. // 必填-商户号,服务商模式下为服务商商户号
  56. 'mch_id' => '',
  57. // 必填-商户秘钥
  58. 'mch_secret_key' => '',
  59. // 必填-商户私钥 字符串或路径
  60. 'mch_secret_cert' => '',
  61. // 必填-商户公钥证书路径
  62. 'mch_public_cert_path' => '',
  63. // 必填
  64. 'notify_url' => '',
  65. // 选填-公众号 的 app_id
  66. 'mp_app_id' => '',
  67. // 选填-小程序 的 app_id
  68. 'mini_app_id' => '',
  69. // 选填-app 的 app_id
  70. 'app_id' => '',
  71. // 选填-合单 app_id
  72. 'combine_app_id' => '',
  73. // 选填-合单商户号
  74. 'combine_mch_id' => '',
  75. // 选填-服务商模式下,子公众号 的 app_id
  76. 'sub_mp_app_id' => '',
  77. // 选填-服务商模式下,子 app 的 app_id
  78. 'sub_app_id' => '',
  79. // 选填-服务商模式下,子小程序 的 app_id
  80. 'sub_mini_app_id' => '',
  81. // 选填-服务商模式下,子商户id
  82. 'sub_mch_id' => '',
  83. // 选填-微信公钥证书路径, optional,强烈建议 php-fpm 模式下配置此参数
  84. 'wechat_public_cert_path' => [
  85. // '45F59D4DABF31918AFCEC556D5D2C6E376675D57' => __DIR__.'/Cert/wechatPublicKey.crt',
  86. ],
  87. // 选填-默认为正常模式。可选为: MODE_NORMAL, MODE_SERVICE
  88. 'mode' => \Yansongda\Pay\Pay::MODE_NORMAL,
  89. ]
  90. ],
  91. 'unipay' => [
  92. 'default' => [
  93. // 必填-商户号
  94. 'mch_id' => '',
  95. // 必填-商户公私钥
  96. 'mch_cert_path' => '',
  97. // 必填-商户公私钥密码
  98. 'mch_cert_password' => '',
  99. // 必填-银联公钥证书路径
  100. 'unipay_public_cert_path' => '',
  101. // 必填
  102. 'return_url' => '',
  103. // 必填
  104. 'notify_url' => '',
  105. ],
  106. ],
  107. 'logger' => [
  108. 'enable' => true,
  109. 'file' => './logs/alipay.log',
  110. 'level' => YII_DEBUG ? 'debug' : 'info', // 建议生产环境等级调整为 info,开发环境为 debug
  111. 'type' => 'single', // optional, 可选 daily.
  112. 'max_file' => 30, // optional, 当 type 为 daily 时有效,默认 30 天
  113. ],
  114. 'http' => [ // optional
  115. 'timeout' => 5.0,
  116. 'connect_timeout' => 5.0,
  117. // 更多配置项请参考 [Guzzle](https://guzzle-cn.readthedocs.io/zh_CN/latest/request-options.html)
  118. ],
  119. ];
  120. /**
  121. * 公用配置
  122. *
  123. * @var
  124. */
  125. protected $rfConfig;
  126. public function init()
  127. {
  128. // 默认读后台配置可切换为根据商户来获取配置
  129. $this->rfConfig = Yii::$app->services->config->configAll();
  130. // 初始化支付宝配置
  131. $this->config['alipay']['default'] = ArrayHelper::merge($this->config['alipay']['default'], [
  132. // 必填-支付宝分配的 app_id
  133. 'app_id' => $this->rfConfig['alipay_app_id'],
  134. // 必填-应用私钥 字符串或路径
  135. 'app_secret_cert' => Yii::getAlias($this->rfConfig['alipay_app_secret_cert']),
  136. // 必填-应用公钥证书 路径
  137. 'app_public_cert_path' => Yii::getAlias($this->rfConfig['alipay_app_public_cert_path']), // /Users/yansongda/pay/cert/appCertPublicKey_2016082000295641.crt
  138. // 必填-支付宝公钥证书 路径
  139. 'alipay_public_cert_path' => Yii::getAlias($this->rfConfig['alipay_public_cert_path']), // /Users/yansongda/pay/cert/alipayCertPublicKey_RSA2.crt
  140. // 必填-支付宝根证书 路径
  141. 'alipay_root_cert_path' => Yii::getAlias($this->rfConfig['alipay_root_cert_path']), // /Users/yansongda/pay/cert/alipayRootCert.crt
  142. 'return_url' => '', // https://yansongda.cn/alipay/return
  143. 'notify_url' => '', // https://yansongda.cn/alipay/notify
  144. ]);
  145. // 初始化微信配置
  146. $this->config['wechat']['default'] = ArrayHelper::merge($this->config['wechat']['default'], [
  147. // 必填-商户号,服务商模式下为服务商商户号
  148. 'mch_id' => $this->rfConfig['wechat_mch_id'],
  149. // 必填-商户秘钥
  150. 'mch_secret_key' => Yii::getAlias($this->rfConfig['wechat_mch_secret_key']),
  151. // 必填-商户私钥证书 字符串或路径
  152. 'mch_secret_cert' => Yii::getAlias($this->rfConfig['wechat_mch_secret_cert']),
  153. // 必填-商户公钥证书路径
  154. 'mch_public_cert_path' => Yii::getAlias($this->rfConfig['wechat_mch_public_cert_path']),
  155. // 必填
  156. 'notify_url' => '',
  157. // 选填-公众号 的 app_id
  158. 'mp_app_id' => $this->rfConfig['wechat_mp_app_id'],
  159. // 选填-小程序 的 app_id
  160. 'mini_app_id' => $this->rfConfig['wechat_mini_app_id'],
  161. // 选填-app 的 app_id
  162. 'app_id' => $this->rfConfig['wechat_app_id'], // 微信开放平台 APPID
  163. // 选填-合单 app_id
  164. 'combine_app_id' => '',
  165. // 选填-合单商户号
  166. 'combine_mch_id' => '',
  167. // 选填-服务商模式下,子公众号 的 app_id
  168. 'sub_mp_app_id' => '',
  169. // 选填-服务商模式下,子 app 的 app_id
  170. 'sub_app_id' => '',
  171. // 选填-服务商模式下,子小程序 的 app_id
  172. 'sub_mini_app_id' => '',
  173. // 选填-服务商模式下,子商户id
  174. 'sub_mch_id' => '',
  175. // 选填-微信公钥证书路径, optional,强烈建议 php-fpm 模式下配置此参数
  176. 'wechat_public_cert_path' => [
  177. // '45F59D4DABF31918AFCEC556D5D2C6E376675D57' => __DIR__.'/Cert/wechatPublicKey.crt',
  178. ],
  179. ]);
  180. // 初始化银联配置
  181. $this->config['unipay']['default'] = ArrayHelper::merge($this->config['unipay']['default'], [
  182. // 必填-商户号
  183. 'mch_id' => $this->rfConfig['unipay_mch_id'],
  184. // 必填-商户公私钥
  185. 'mch_cert_path' => Yii::getAlias($this->rfConfig['unipay_mch_cert_path']),
  186. // 必填-商户公私钥密码
  187. 'mch_cert_password' => $this->rfConfig['unipay_mch_cert_password'],
  188. // 必填-银联公钥证书路径
  189. 'unipay_public_cert_path' => Yii::getAlias($this->rfConfig['unipay_public_cert_path']),
  190. // 必填
  191. 'return_url' => '',
  192. // 必填
  193. 'notify_url' => '',
  194. ]);
  195. // 日志目录
  196. $this->config['logger']['file'] = Yii::getAlias('@runtime') . '/logs/pay-' . date('Y-m-d') . '.log';
  197. // 强制覆盖配置
  198. $this->config['_force'] = true;
  199. parent::init();
  200. }
  201. /**
  202. * 支付宝支付
  203. *
  204. * @param array $config
  205. * @return AliPay
  206. * @throws \yii\base\InvalidConfigException
  207. */
  208. public function alipay(array $config = [])
  209. {
  210. !empty($config) && $this->config['alipay']['default'] = ArrayHelper::merge($this->config['alipay']['default'], $config);
  211. return new AliPay($this->config);
  212. }
  213. /**
  214. * 微信支付
  215. *
  216. * @param array $config
  217. * @return WechatPay
  218. */
  219. public function wechat(array $config = [])
  220. {
  221. !empty($config) && $this->config['wechat']['default'] = ArrayHelper::merge($this->config['wechat']['default'], $config);
  222. return new WechatPay($this->config);
  223. }
  224. /**
  225. * 银联支付
  226. *
  227. * @param array $config
  228. * @return UniPay
  229. * @throws \yii\base\InvalidConfigException
  230. */
  231. public function unipay(array $config = [])
  232. {
  233. !empty($config) && $this->config['unipay']['default'] = ArrayHelper::merge($this->config['unipay']['default'], $config);
  234. return new UniPay($this->config);
  235. }
  236. /**
  237. * 字节跳动支付
  238. *
  239. * @param array $config
  240. * @return ByteDancePay
  241. * @throws \yii\base\InvalidConfigException
  242. */
  243. public function byteDance(array $config = [])
  244. {
  245. return new ByteDancePay(ArrayHelper::merge([
  246. 'app_id' => $this->rfConfig['byte_dance_mini_app_id'],
  247. 'app_secret' => $this->rfConfig['byte_dance_mini_app_secret'],
  248. 'app_salt' => $this->rfConfig['byte_dance_mini_app_salt'], // SALT
  249. 'app_token' => $this->rfConfig['byte_dance_mini_app_token'], // SALT
  250. 'notify_url' => '',
  251. 'return_url' => '',
  252. ], $config));
  253. }
  254. /**
  255. * Stripe
  256. *
  257. * 测试的接口,在key 结尾加 _test 字符串.
  258. * Test card: 4000001240000000
  259. * @param array $config
  260. * @return Stripe
  261. * @throws \yii\base\InvalidConfigException
  262. */
  263. public function stripe(array $config = [])
  264. {
  265. return new Stripe(ArrayHelper::merge([
  266. 'publishable_key' => $this->rfConfig['stripe_publishable_key'],
  267. 'secret_key' => $this->rfConfig['stripe_secret_key'],
  268. ], $config));
  269. }
  270. /**
  271. * @param $name
  272. * @return mixed
  273. * @throws \Exception
  274. */
  275. public function __get($name)
  276. {
  277. try {
  278. return parent::__get($name);
  279. } catch (\Exception $e) {
  280. if ($this->$name()) {
  281. return $this->$name([]);
  282. } else {
  283. throw $e->getPrevious();
  284. }
  285. }
  286. }
  287. }
粤ICP备19079148号