llpaypayment.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: tandunzhao
  5. * Date: 2017/12/28
  6. * Time: 上午9:22
  7. */
  8. namespace App\Libs\lianlianpay;
  9. class llpaypayment
  10. {
  11. //平台来源
  12. public static $platform = 'pay.zhuishuyun.com';
  13. //版本号
  14. public static $api_version = '1.0';
  15. //服务器异步通知地址
  16. public static $notify_url = 'http://47.97.120.133:8094/api/tradepayapi/receiveNotify.htm';
  17. //实时付款交易接口地址
  18. public static $llpay_payment_url = 'https://instantpay.lianlianpay.com/paymentapi/payment.htm';
  19. //查询付款结果
  20. public static $llpayPaymentQuery = 'https://instantpay.lianlianpay.com/paymentapi/queryPayment.htm';
  21. //账户余额查询
  22. public static $llPayTraderAcctQuery = "https://traderapi.lianlianpay.com/traderAcctQuery.htm";
  23. /**
  24. * 连连代付
  25. * @param $transactionSerialNumber [交易流水号]
  26. * @param $bankCode [银行代码]
  27. * @param @param $bankName [交易银行名称]
  28. * @param $bankAccountNO [银行卡账号]
  29. * @param $bankAccountName [银行卡户主名称]
  30. * @param $amount [金额] 元元元
  31. * @param $summary [交易附言]
  32. * @param $remark [备注]
  33. * @param $channelId [渠道ID]
  34. * @param $is_company 0:私人; 1:公司
  35. * @return mixed
  36. */
  37. public static function payLianLianPay($transactionSerialNumber,
  38. $bankCode,
  39. $bankName,
  40. $bankAccountNO,
  41. $bankAccountName,
  42. $amount,
  43. $summary,
  44. $remark,
  45. $channelId,
  46. $is_company) {
  47. //构造要请求的参数数组,无需改动
  48. $llpayconfig = llpay_config::getLlpayConfig();
  49. //商户时间
  50. $dt_order = date("YmdHis");
  51. //对私标记
  52. $flag_card = "0";
  53. if($is_company == 1) {
  54. $flag_card = "1";
  55. }
  56. //dd($flag_card);
  57. $parameter = array (
  58. "oid_partner" => trim($llpayconfig['oid_partner']),
  59. "sign_type" => trim($llpayconfig['sign_type']),
  60. "no_order" => $transactionSerialNumber,//商户付款流水号
  61. "dt_order" => $dt_order,//商户时间
  62. "money_order" => $amount,//金额
  63. "acct_name" => $bankAccountName,//收款人姓名
  64. "card_no" => $bankAccountNO,//银行账号
  65. "info_order" => $summary,//订单描述
  66. "flag_card" => $flag_card,//对私标记
  67. "notify_url" => self::$notify_url,
  68. "platform" => self::$platform,
  69. "api_version" => self::$api_version
  70. );
  71. //建立请求
  72. $llpaySubmit = new llpay_apipost_submit($llpayconfig);
  73. //对参数排序加签名
  74. $sortPara = $llpaySubmit->buildRequestPara($parameter);
  75. //传json字符串
  76. $json = json_encode($sortPara);
  77. $parameterRequest = array (
  78. "oid_partner" => trim($llpayconfig['oid_partner']),
  79. "pay_load" => llpay_security::ll_encrypt($json,$llpayconfig['LIANLIAN_PUBLICK_KEY']) //请求参数加密
  80. );
  81. // dd($parameterRequest);
  82. // var_dump('$parameterRequest');
  83. // var_dump($parameterRequest);
  84. $html_text = $llpaySubmit->buildRequestJSON($parameterRequest, self::$llpay_payment_url);
  85. //调用付款申请接口,同步返回0000,是指创建连连支付单成功,订单处于付款处理中状态,最终的付款状态由异步通知告知
  86. //出现1002,2005,4006,4007,4009,9999这6个返回码时或者没返回码,抛exception(或者对除了0000之后的code都查询一遍查询接口)调用付款结果查询接口,明确订单状态,不能私自设置订单为失败状态,以免造成这笔订单在连连付款成功了,
  87. //而商户设置为失败,用户重新发起付款请求,造成重复付款,商户资金损失
  88. //对连连响应报文内容需要用连连公钥验签
  89. // $html_text = "[".$transactionSerialNumber."]".$html_text;
  90. // dd($html_text);
  91. /**
  92. * {
  93. * "no_order": "2017122916450888_1",
  94. * "oid_partner": "201711230001180015",
  95. * "oid_paybill": "2017122996863947",
  96. * "ret_code": "0000",
  97. * "ret_msg": "交易成功",
  98. * "sign": "HQW1jA0V/MJHiGIsv9sAt3olbGzatooscgXKEsLNrtolDJz42TRw7FUQxJ6ePdFN52ZS/IS/bMPVFWhmTGIItS9nDRcL5BcU7VSfeDY7VmlXlfwUNpV6W7pe3FKTX0ASFaA++XaT6pQlCCjkRol1A5IDxEHBF+p3Oky9jd8kfrI=",
  99. * "sign_type": "RSA"
  100. * }
  101. */
  102. $resultCode = 0;
  103. $resultMsg = "";
  104. if($html_text!=FALSE) {
  105. if($html_text.startsWith("{") && $html_text.endsWith("}")) {
  106. $resultCode = 1;
  107. $result = json_decode($html_text);
  108. if($result && isset($result->ret_msg)) {
  109. $resultMsg = $result->ret_msg;
  110. }
  111. if($result && isset($result->ret_code)) {
  112. $RET_CODE = $result->ret_code;
  113. if ($RET_CODE == "0000") {
  114. if(isset($result->result_pay)) {
  115. $result_pay = $result->result_pay;
  116. if($result_pay == "SUCCESS" ) {
  117. $resultMsg = "处理成功";
  118. } else if($result_pay == "APPLY"
  119. || $result_pay == "CHECK"
  120. || $result_pay == "PROCESSING" ) {
  121. } else if($result_pay == "CANCEL"
  122. || $result_pay == "FAILURE"
  123. || $result_pay == "CLOSED") {
  124. $resultCode = 0;
  125. }
  126. }
  127. } else if($RET_CODE == "1001"// 商户请求签名未通过
  128. || $RET_CODE == "1002"//商户付款流水号重复
  129. || $RET_CODE == "1004"// 商户请求参数校验错误,商户请求参数 非法
  130. || $RET_CODE == "1005"// 不支持该银行账户类型
  131. || $RET_CODE == "1008"// 商户请求IP错误
  132. || $RET_CODE == "3001"// 非法商户
  133. || $RET_CODE == "4003"// 收款银行卡和姓名不一至
  134. || $RET_CODE == "4005"// 商户没有实时付款权限
  135. || $RET_CODE == "4006"// 敏感信息加密异常
  136. || $RET_CODE == "4007"// 敏感信息解密异常
  137. || $RET_CODE == "4012"// 银行卡查询异常
  138. || $RET_CODE == "4013"// 账户异常
  139. || $RET_CODE == "4014"// 付款订单创建失败
  140. || $RET_CODE == "4015"// 打款行号查询失败
  141. || $RET_CODE == "9104"// 账户余额不足
  142. || $RET_CODE == "9910"// 风险等级过高
  143. || $RET_CODE == "9911"// 超过单笔限额
  144. || $RET_CODE == "9912"// 超过单日限额
  145. || $RET_CODE == "9913"// 超过单月限额
  146. || $RET_CODE == "9999"// 系统错误
  147. || $RET_CODE == "1004") {
  148. $resultCode = 0;
  149. }
  150. }
  151. } else {
  152. $resultMsg = "验签失败";
  153. }
  154. } else {
  155. $resultMsg = "验签失败";
  156. }
  157. $reqData = [
  158. 'code' => $resultCode,
  159. 'msg' => $resultMsg,
  160. 'http_result_data' => $html_text
  161. ];
  162. return $reqData;
  163. }
  164. /**
  165. * 查询付款结果
  166. * @param $transactionSerialNumber
  167. * @param $reqSn
  168. * @return array
  169. */
  170. public static function payQuery($transactionSerialNumber, $reqSn) {
  171. $llpayconfig = llpay_config::getLlpayConfig();
  172. $parameter = array (
  173. "oid_partner" => trim($llpayconfig['oid_partner']),
  174. "platform" => self::$platform,
  175. "api_version" => self::$api_version,
  176. "sign_type" => trim($llpayconfig['sign_type']),
  177. "no_order" => $transactionSerialNumber,//商户付款流水号
  178. "oid_paybill" => '',//连连支付单号,可不传
  179. );
  180. //建立请求
  181. $llpaySubmit = new llpay_apipost_submit($llpayconfig);
  182. //对参数排序加签名
  183. $sortPara = $llpaySubmit->buildRequestPara($parameter);
  184. $html_text = $llpaySubmit->buildRequestJSON($sortPara, self::$llpayPaymentQuery);
  185. // dd($html_text);
  186. /**
  187. * {
  188. * "dt_order": "20171229164508", //商户下单时间 YYYYMMDDH24MISS 14位数字,精确到秒
  189. * "info_order": "summary", //订单描述
  190. * "money_order": "0.01", //付款金额 付款金额大于 0 ,精确到小数点后两位
  191. * "no_order": "2017122916450888_1", //商户付款流水号 商户系统唯一标识该付款的流水号
  192. * "oid_partner": "201711230001180015",//
  193. * "oid_paybill": "2017122996863947",//连连支付支付单号 银通付款流水号,付款支付单创建成功才有
  194. * "result_pay": "SUCCESS",//付款结果
  195. * "ret_code": "0000",
  196. * "ret_msg": "交易成功", //
  197. * "settle_date": "20171229", //清算日期 付款成功后有
  198. * "sign": "kdhZczxi4oh7JSndKbuxkwhIlpiiVelpH5yzdpTTL1kII2glR6fioMiWlhaTiBh9GrWC9OGJugO0dEEhoSxl2umMP8QUWZdbajBv3+b3fTaNzDX29vFDasmHDryyS2nhJom/Fm/4L56b2CcAjMbOeBefK4grxtdm5w3/KlTqPsI=",
  199. * "sign_type": "RSA"
  200. * }
  201. */
  202. //中间状态,等待下次查询
  203. $resultCode = 2;
  204. $resultMsg = "";
  205. if($html_text!=FALSE) {
  206. if($html_text.startsWith("{") && $html_text.endsWith("}")) {
  207. $result = json_decode($html_text);
  208. if($result && isset($result->ret_msg)) {
  209. $resultMsg = $result->ret_msg;
  210. }
  211. if($result && isset($result->ret_code)) {
  212. $RET_CODE = $result->ret_code;
  213. if ($RET_CODE == "0000") {
  214. if(isset($result->result_pay)) {
  215. $result_pay = $result->result_pay;
  216. if($result_pay == "SUCCESS" ) {
  217. $resultCode = 1;
  218. $resultMsg = "处理成功";
  219. } else if($result_pay == "APPLY" //付款申请
  220. || $result_pay == "CHECK" //复核申请
  221. || $result_pay == "PROCESSING" ) { //付款处理中
  222. } else if($result_pay == "CANCEL" //退款
  223. || $result_pay == "FAILURE" //失败
  224. || $result_pay == "CLOSED") { //关闭
  225. //退款, 失败, 关闭
  226. $resultCode = 0;
  227. }
  228. }
  229. }
  230. }
  231. }
  232. } else {
  233. $resultCode = 0;
  234. $resultMsg = "验签失败";
  235. // print_r("验签结果:验签失败,请检查通联公钥证书是否正确");
  236. }
  237. $reqData = [
  238. 'code' => $resultCode,
  239. 'msg' => $resultMsg,
  240. 'http_result_data' => $html_text
  241. ];
  242. return $reqData;
  243. }
  244. /**
  245. * 账户信息查询
  246. * @param $reqSn
  247. * @return array balance:单位分
  248. */
  249. public static function payAccountInfo($reqSn) {
  250. //构造要请求的参数数组,无需改动
  251. $llpayconfig = llpay_config::getLlpayConfig();
  252. $parameter = array (
  253. "oid_partner" => trim($llpayconfig['oid_partner']),
  254. "sign_type" => trim($llpayconfig['sign_type']),
  255. "api_version" => self::$api_version,
  256. );
  257. //建立请求
  258. $llpaySubmit = new llpay_apipost_submit($llpayconfig);
  259. //对参数排序加签名
  260. $sortPara = $llpaySubmit->buildRequestPara($parameter);
  261. $html_text = $llpaySubmit->buildRequestJSON($sortPara, self::$llPayTraderAcctQuery);
  262. // dd($html_text);
  263. /*
  264. * {
  265. * "amt_balance": "99.99",//该金额可作商户提现
  266. * "amt_unsettle": "0.00",//该金额可进行退款,结转,不建议开通商户站充值业务的商户使用接口查询未结算余额作为退款依据
  267. * "ret_code": "0000",
  268. * "ret_msg": "交易成功",
  269. * "sign": "eVy8IBAQzDhKJTgG9DzRNB86WbDnB35tQq8ZkMJ1D4KJ+tXtbbkk1lVToBgnmkTnnoyeVq3Y7D46aED0VmVz25G8ZLpIU6OLh18Z3zf/WA9p7LiUqDTZUT2w3FB+fRo+5vPHEA9kfnS6L00c2DESJr042RGPqzEQE3VifHf5jNw=",
  270. * "sign_type": "RSA"
  271. * }
  272. */
  273. $resultCode = 0;
  274. $resultMsg = "";
  275. $resultBalance = 0;//余额
  276. if($html_text!=FALSE) {
  277. if($html_text.startsWith("{") && $html_text.endsWith("}")) {
  278. $result = json_decode($html_text);
  279. if($result && isset($result->ret_code)) {
  280. $RET_CODE = $result->ret_code;
  281. if($RET_CODE == "0000") {
  282. $resultBalance = ((float)$result->amt_balance) * 100;
  283. $resultMsg = "查询成功";
  284. $resultCode = 1;
  285. } else {
  286. $ERR_MSG = $result->ret_msg;
  287. $resultMsg = $ERR_MSG;
  288. $resultCode = 0;
  289. }
  290. }
  291. }
  292. } else {
  293. $resultCode = 0;
  294. $resultMsg = "验签失败";
  295. // print_r("验签结果:验签失败,请检查通联公钥证书是否正确");
  296. }
  297. $reqData = [
  298. 'code' => $resultCode,
  299. 'msg' => $resultMsg,
  300. 'balance' => $resultBalance,
  301. 'http_result_data' => $html_text
  302. ];
  303. return $reqData;
  304. }
  305. }