WxPay.Data.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703
  1. <?php
  2. /**
  3. * 2015-06-29 修复签名问题
  4. **/
  5. require_once IA_ROOT . "/addons/zh_jdgjb/cert/WxPay.Exception.php";
  6. /**
  7. *
  8. * 数据对象基础类,该类中定义数据类最基本的行为,包括:
  9. * 计算/设置/获取签名、输出xml格式的参数、从xml读取数据对象等
  10. * @author widyhu
  11. *
  12. */
  13. class WxPayDataBase
  14. {
  15. protected $values = array();
  16. /**
  17. * 设置签名,详见签名生成算法
  18. * @param string $value
  19. **/
  20. public function SetSign($key)
  21. {
  22. $sign = $this->MakeSign($key);
  23. $this->values['sign'] = $sign;
  24. return $sign;
  25. }
  26. /**
  27. * 获取签名,详见签名生成算法的值
  28. * @return 值
  29. **/
  30. public function GetSign()
  31. {
  32. return $this->values['sign'];
  33. }
  34. /**
  35. * 判断签名,详见签名生成算法是否存在
  36. * @return true 或 false
  37. **/
  38. public function IsSignSet()
  39. {
  40. return array_key_exists('sign', $this->values);
  41. }
  42. /**
  43. * 输出xml字符
  44. * @throws WxPayException
  45. **/
  46. public function ToXml()
  47. {
  48. if(!is_array($this->values)
  49. || count($this->values) <= 0)
  50. {
  51. throw new WxPayException("数组数据异常!");
  52. }
  53. $xml = "<xml>";
  54. foreach ($this->values as $key=>$val)
  55. {
  56. if (is_numeric($val)){
  57. $xml.="<".$key.">".$val."</".$key.">";
  58. }else{
  59. $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
  60. }
  61. }
  62. $xml.="</xml>";
  63. return $xml;
  64. }
  65. /**
  66. * 将xml转为array
  67. * @param string $xml
  68. * @throws WxPayException
  69. */
  70. public function FromXml($xml)
  71. {
  72. if(!$xml){
  73. throw new WxPayException("xml数据异常!");
  74. }
  75. //将XML转为array
  76. //禁止引用外部xml实体
  77. libxml_disable_entity_loader(true);
  78. $this->values = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
  79. return $this->values;
  80. }
  81. /**
  82. * 格式化参数格式化成url参数
  83. */
  84. public function ToUrlParams()
  85. {
  86. $buff = "";
  87. foreach ($this->values as $k => $v)
  88. {
  89. if($k != "sign" && $v != "" && !is_array($v)){
  90. $buff .= $k . "=" . $v . "&";
  91. }
  92. }
  93. $buff = trim($buff, "&");
  94. return $buff;
  95. }
  96. /**
  97. * 生成签名
  98. * @return 签名,本函数不覆盖sign成员变量,如要设置签名需要调用SetSign方法赋值
  99. */
  100. public function MakeSign($key)
  101. {
  102. //签名步骤一:按字典序排序参数
  103. ksort($this->values);
  104. $string = $this->ToUrlParams();
  105. //签名步骤二:在string后加入KEY
  106. $string = $string . "&key=".$key;
  107. //签名步骤三:MD5加密
  108. $string = md5($string);
  109. //签名步骤四:所有字符转为大写
  110. $result = strtoupper($string);
  111. return $result;
  112. }
  113. /**
  114. * 获取设置的值
  115. */
  116. public function GetValues()
  117. {
  118. return $this->values;
  119. }
  120. }
  121. /**
  122. *
  123. * 订单查询输入对象
  124. * @author widyhu
  125. *
  126. */
  127. class WxPayOrderQuery extends WxPayDataBase
  128. {
  129. /**
  130. * 设置微信分配的公众账号ID
  131. * @param string $value
  132. **/
  133. public function SetAppid($value)
  134. {
  135. $this->values['appid'] = $value;
  136. }
  137. /**
  138. * 获取微信分配的公众账号ID的值
  139. * @return 值
  140. **/
  141. public function GetAppid()
  142. {
  143. return $this->values['appid'];
  144. }
  145. /**
  146. * 判断微信分配的公众账号ID是否存在
  147. * @return true 或 false
  148. **/
  149. public function IsAppidSet()
  150. {
  151. return array_key_exists('appid', $this->values);
  152. }
  153. /**
  154. * 设置微信支付分配的商户号
  155. * @param string $value
  156. **/
  157. public function SetMch_id($value)
  158. {
  159. $this->values['mch_id'] = $value;
  160. }
  161. /**
  162. * 获取微信支付分配的商户号的值
  163. * @return 值
  164. **/
  165. public function GetMch_id()
  166. {
  167. return $this->values['mch_id'];
  168. }
  169. /**
  170. * 判断微信支付分配的商户号是否存在
  171. * @return true 或 false
  172. **/
  173. public function IsMch_idSet()
  174. {
  175. return array_key_exists('mch_id', $this->values);
  176. }
  177. /**
  178. * 设置微信的订单号,优先使用
  179. * @param string $value
  180. **/
  181. public function SetTransaction_id($value)
  182. {
  183. $this->values['transaction_id'] = $value;
  184. }
  185. /**
  186. * 获取微信的订单号,优先使用的值
  187. * @return 值
  188. **/
  189. public function GetTransaction_id()
  190. {
  191. return $this->values['transaction_id'];
  192. }
  193. /**
  194. * 判断微信的订单号,优先使用是否存在
  195. * @return true 或 false
  196. **/
  197. public function IsTransaction_idSet()
  198. {
  199. return array_key_exists('transaction_id', $this->values);
  200. }
  201. /**
  202. * 设置商户系统内部的订单号,当没提供transaction_id时需要传这个。
  203. * @param string $value
  204. **/
  205. public function SetOut_trade_no($value)
  206. {
  207. $this->values['out_trade_no'] = $value;
  208. }
  209. /**
  210. * 获取商户系统内部的订单号,当没提供transaction_id时需要传这个。的值
  211. * @return 值
  212. **/
  213. public function GetOut_trade_no()
  214. {
  215. return $this->values['out_trade_no'];
  216. }
  217. /**
  218. * 判断商户系统内部的订单号,当没提供transaction_id时需要传这个。是否存在
  219. * @return true 或 false
  220. **/
  221. public function IsOut_trade_noSet()
  222. {
  223. return array_key_exists('out_trade_no', $this->values);
  224. }
  225. /**
  226. * 设置随机字符串,不长于32位。推荐随机数生成算法
  227. * @param string $value
  228. **/
  229. public function SetNonce_str($value)
  230. {
  231. $this->values['nonce_str'] = $value;
  232. }
  233. /**
  234. * 获取随机字符串,不长于32位。推荐随机数生成算法的值
  235. * @return 值
  236. **/
  237. public function GetNonce_str()
  238. {
  239. return $this->values['nonce_str'];
  240. }
  241. /**
  242. * 判断随机字符串,不长于32位。推荐随机数生成算法是否存在
  243. * @return true 或 false
  244. **/
  245. public function IsNonce_strSet()
  246. {
  247. return array_key_exists('nonce_str', $this->values);
  248. }
  249. }
  250. /**
  251. *
  252. * 接口调用结果类
  253. * @author widyhu
  254. *
  255. */
  256. class WxPayResults extends WxPayDataBase
  257. {
  258. /**
  259. *
  260. * 检测签名
  261. */
  262. public function CheckSign()
  263. {
  264. //fix异常
  265. if(!$this->IsSignSet()){
  266. throw new WxPayException("签名错误1");
  267. }
  268. $sign = $this->MakeSign();
  269. if($this->GetSign() == $sign){
  270. return true;
  271. }
  272. throw new WxPayException("签名错误2");
  273. }
  274. /**
  275. *
  276. * 使用数组初始化
  277. * @param array $array
  278. */
  279. public function FromArray($array)
  280. {
  281. $this->values = $array;
  282. }
  283. /**
  284. *
  285. * 使用数组初始化对象
  286. * @param array $array
  287. * @param 是否检测签名 $noCheckSign
  288. */
  289. public static function InitFromArray($array, $noCheckSign = false)
  290. {
  291. $obj = new self();
  292. $obj->FromArray($array);
  293. if($noCheckSign == false){
  294. }
  295. return $obj;
  296. }
  297. /**
  298. *
  299. * 设置参数
  300. * @param string $key
  301. * @param string $value
  302. */
  303. public function SetData($key, $value)
  304. {
  305. $this->values[$key] = $value;
  306. }
  307. /**
  308. * 将xml转为array
  309. * @param string $xml
  310. * @throws WxPayException
  311. */
  312. public static function Init($xml)
  313. {
  314. $obj = new self();
  315. $obj->FromXml($xml);
  316. //fix bug 2015-06-29
  317. if($obj->values['return_code'] != 'SUCCESS'){
  318. return $obj->GetValues();
  319. }
  320. return $obj->GetValues();
  321. }
  322. }
  323. /**
  324. *
  325. * 回调基础类
  326. * @author widyhu
  327. *
  328. */
  329. class WxPayNotifyReply extends WxPayDataBase
  330. {
  331. /**
  332. *
  333. * 设置错误码 FAIL 或者 SUCCESS
  334. * @param string
  335. */
  336. public function SetReturn_code($return_code)
  337. {
  338. $this->values['return_code'] = $return_code;
  339. }
  340. /**
  341. *
  342. * 获取错误码 FAIL 或者 SUCCESS
  343. * @return string $return_code
  344. */
  345. public function GetReturn_code()
  346. {
  347. return $this->values['return_code'];
  348. }
  349. /**
  350. *
  351. * 设置错误信息
  352. * @param string $return_code
  353. */
  354. public function SetReturn_msg($return_msg)
  355. {
  356. $this->values['return_msg'] = $return_msg;
  357. }
  358. /**
  359. *
  360. * 获取错误信息
  361. * @return string
  362. */
  363. public function GetReturn_msg()
  364. {
  365. return $this->values['return_msg'];
  366. }
  367. /**
  368. *
  369. * 设置返回参数
  370. * @param string $key
  371. * @param string $value
  372. */
  373. public function SetData($key, $value)
  374. {
  375. $this->values[$key] = $value;
  376. }
  377. }
  378. /**
  379. *
  380. * 提交退款输入对象
  381. * @author widyhu
  382. *
  383. */
  384. class WxPayRefund extends WxPayDataBase
  385. {
  386. /**
  387. * 设置微信分配的公众账号ID
  388. * @param string $value
  389. **/
  390. public function SetAppid($value)
  391. {
  392. $this->values['appid'] = $value;
  393. }
  394. /**
  395. * 获取微信分配的公众账号ID的值
  396. * @return 值
  397. **/
  398. public function GetAppid()
  399. {
  400. return $this->values['appid'];
  401. }
  402. /**
  403. * 判断微信分配的公众账号ID是否存在
  404. * @return true 或 false
  405. **/
  406. public function IsAppidSet()
  407. {
  408. return array_key_exists('appid', $this->values);
  409. }
  410. /**
  411. * 设置微信支付分配的商户号
  412. * @param string $value
  413. **/
  414. public function SetMch_id($value)
  415. {
  416. $this->values['mch_id'] = $value;
  417. }
  418. /**
  419. * 获取微信支付分配的商户号的值
  420. * @return 值
  421. **/
  422. public function GetMch_id()
  423. {
  424. return $this->values['mch_id'];
  425. }
  426. /**
  427. * 判断微信支付分配的商户号是否存在
  428. * @return true 或 false
  429. **/
  430. public function IsMch_idSet()
  431. {
  432. return array_key_exists('mch_id', $this->values);
  433. }
  434. /**
  435. * 设置微信支付分配的终端设备号,与下单一致
  436. * @param string $value
  437. **/
  438. public function SetDevice_info($value)
  439. {
  440. $this->values['device_info'] = $value;
  441. }
  442. /**
  443. * 获取微信支付分配的终端设备号,与下单一致的值
  444. * @return 值
  445. **/
  446. public function GetDevice_info()
  447. {
  448. return $this->values['device_info'];
  449. }
  450. /**
  451. * 判断微信支付分配的终端设备号,与下单一致是否存在
  452. * @return true 或 false
  453. **/
  454. public function IsDevice_infoSet()
  455. {
  456. return array_key_exists('device_info', $this->values);
  457. }
  458. /**
  459. * 设置随机字符串,不长于32位。推荐随机数生成算法
  460. * @param string $value
  461. **/
  462. public function SetNonce_str($value)
  463. {
  464. $this->values['nonce_str'] = $value;
  465. }
  466. /**
  467. * 获取随机字符串,不长于32位。推荐随机数生成算法的值
  468. * @return 值
  469. **/
  470. public function GetNonce_str()
  471. {
  472. return $this->values['nonce_str'];
  473. }
  474. /**
  475. * 判断随机字符串,不长于32位。推荐随机数生成算法是否存在
  476. * @return true 或 false
  477. **/
  478. public function IsNonce_strSet()
  479. {
  480. return array_key_exists('nonce_str', $this->values);
  481. }
  482. /**
  483. * 设置微信订单号
  484. * @param string $value
  485. **/
  486. public function SetTransaction_id($value)
  487. {
  488. $this->values['transaction_id'] = $value;
  489. }
  490. /**
  491. * 获取微信订单号的值
  492. * @return 值
  493. **/
  494. public function GetTransaction_id()
  495. {
  496. return $this->values['transaction_id'];
  497. }
  498. /**
  499. * 判断微信订单号是否存在
  500. * @return true 或 false
  501. **/
  502. public function IsTransaction_idSet()
  503. {
  504. return array_key_exists('transaction_id', $this->values);
  505. }
  506. /**
  507. * 设置商户系统内部的订单号,transaction_id、out_trade_no二选一,如果同时存在优先级:transaction_id> out_trade_no
  508. * @param string $value
  509. **/
  510. public function SetOut_trade_no($value)
  511. {
  512. $this->values['out_trade_no'] = $value;
  513. }
  514. /**
  515. * 获取商户系统内部的订单号,transaction_id、out_trade_no二选一,如果同时存在优先级:transaction_id> out_trade_no的值
  516. * @return 值
  517. **/
  518. public function GetOut_trade_no()
  519. {
  520. return $this->values['out_trade_no'];
  521. }
  522. /**
  523. * 判断商户系统内部的订单号,transaction_id、out_trade_no二选一,如果同时存在优先级:transaction_id> out_trade_no是否存在
  524. * @return true 或 false
  525. **/
  526. public function IsOut_trade_noSet()
  527. {
  528. return array_key_exists('out_trade_no', $this->values);
  529. }
  530. /**
  531. * 设置商户系统内部的退款单号,商户系统内部唯一,同一退款单号多次请求只退一笔
  532. * @param string $value
  533. **/
  534. public function SetOut_refund_no($value)
  535. {
  536. $this->values['out_refund_no'] = $value;
  537. }
  538. /**
  539. * 获取商户系统内部的退款单号,商户系统内部唯一,同一退款单号多次请求只退一笔的值
  540. * @return 值
  541. **/
  542. public function GetOut_refund_no()
  543. {
  544. return $this->values['out_refund_no'];
  545. }
  546. /**
  547. * 判断商户系统内部的退款单号,商户系统内部唯一,同一退款单号多次请求只退一笔是否存在
  548. * @return true 或 false
  549. **/
  550. public function IsOut_refund_noSet()
  551. {
  552. return array_key_exists('out_refund_no', $this->values);
  553. }
  554. /**
  555. * 设置订单总金额,单位为分,只能为整数,详见支付金额
  556. * @param string $value
  557. **/
  558. public function SetTotal_fee($value)
  559. {
  560. $this->values['total_fee'] = $value;
  561. }
  562. /**
  563. * 获取订单总金额,单位为分,只能为整数,详见支付金额的值
  564. * @return 值
  565. **/
  566. public function GetTotal_fee()
  567. {
  568. return $this->values['total_fee'];
  569. }
  570. /**
  571. * 判断订单总金额,单位为分,只能为整数,详见支付金额是否存在
  572. * @return true 或 false
  573. **/
  574. public function IsTotal_feeSet()
  575. {
  576. return array_key_exists('total_fee', $this->values);
  577. }
  578. /**
  579. * 设置退款总金额,订单总金额,单位为分,只能为整数,详见支付金额
  580. * @param string $value
  581. **/
  582. public function SetRefund_fee($value)
  583. {
  584. $this->values['refund_fee'] = $value;
  585. }
  586. /**
  587. * 获取退款总金额,订单总金额,单位为分,只能为整数,详见支付金额的值
  588. * @return 值
  589. **/
  590. public function GetRefund_fee()
  591. {
  592. return $this->values['refund_fee'];
  593. }
  594. /**
  595. * 判断退款总金额,订单总金额,单位为分,只能为整数,详见支付金额是否存在
  596. * @return true 或 false
  597. **/
  598. public function IsRefund_feeSet()
  599. {
  600. return array_key_exists('refund_fee', $this->values);
  601. }
  602. /**
  603. * 设置货币类型,符合ISO 4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型
  604. * @param string $value
  605. **/
  606. public function SetRefund_fee_type($value)
  607. {
  608. $this->values['refund_fee_type'] = $value;
  609. }
  610. /**
  611. * 获取货币类型,符合ISO 4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型的值
  612. * @return 值
  613. **/
  614. public function GetRefund_fee_type()
  615. {
  616. return $this->values['refund_fee_type'];
  617. }
  618. /**
  619. * 判断货币类型,符合ISO 4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型是否存在
  620. * @return true 或 false
  621. **/
  622. public function IsRefund_fee_typeSet()
  623. {
  624. return array_key_exists('refund_fee_type', $this->values);
  625. }
  626. /**
  627. * 设置操作员帐号, 默认为商户号
  628. * @param string $value
  629. **/
  630. public function SetOp_user_id($value)
  631. {
  632. $this->values['op_user_id'] = $value;
  633. }
  634. /**
  635. * 获取操作员帐号, 默认为商户号的值
  636. * @return 值
  637. **/
  638. public function GetOp_user_id()
  639. {
  640. return $this->values['op_user_id'];
  641. }
  642. /**
  643. * 判断操作员帐号, 默认为商户号是否存在
  644. * @return true 或 false
  645. **/
  646. public function IsOp_user_idSet()
  647. {
  648. return array_key_exists('op_user_id', $this->values);
  649. }
  650. }