Payfort.php 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. <?php
  2. namespace Payment\Lib;
  3. use Dever;
  4. class Payfort extends Core
  5. {
  6. private $config = array();
  7. private $language = 'en';
  8. private $url = 'https://checkout.payfort.com/FortAPI/paymentPage';
  9. public function __construct($name, $config)
  10. {
  11. $this->name = $name;
  12. $this->config = $config;
  13. }
  14. private function getType($type, $currency)
  15. {
  16. if ($type < 5 && $currency == 'SAR') {
  17. $type = 4;
  18. }
  19. $name = $value = $method = $command = '';
  20. switch ($type) {
  21. case 1:
  22. # 目前不支持
  23. $name = 'Pay with credit cards (Redirection)';
  24. $method = 'redirection';
  25. break;
  26. case 2:
  27. $name = 'Pay with installments (Redirection)';
  28. $method = 'redirection';
  29. $command = 'PURCHASE';
  30. break;
  31. case 3:
  32. $name = 'Pay with NAPS';
  33. $value = 'NAPS';
  34. $currency = 'NAPS';
  35. $method = 'redirection';
  36. break;
  37. case 4:
  38. $name = 'Pay with SADAD';
  39. $value = 'SADAD';
  40. $currency = 'SAR';
  41. $method = 'redirection';
  42. $command = 'AUTHORIZATION';
  43. break;
  44. case 11:
  45. $name = 'Pay with credit cards (Merchant Page)';
  46. $method = 'page';
  47. $currency = '';
  48. $command = 'TOKENIZATION';
  49. break;
  50. case 12:
  51. $name = 'Pay with installments (Merchant Page)';
  52. $method = 'page';
  53. $currency = '';
  54. $command = 'TOKENIZATION';
  55. break;
  56. case 21:
  57. $name = 'Pay with credit cards (Merchant Page 2.0)';
  58. $method = 'page_v2';
  59. $currency = '';
  60. $command = 'TOKENIZATION';
  61. break;
  62. }
  63. $currency = strtoupper($currency);
  64. return array
  65. (
  66. 'id' => $type,
  67. 'name' => $name,
  68. 'value' => $value,
  69. 'method' => $method,
  70. 'currency' => $currency,
  71. 'command' => $command,
  72. );
  73. }
  74. /**
  75. * 获取统一下单的基本信息
  76. */
  77. public function request($type, $uid, $account, $product_name, $amount, $currency, $data = array())
  78. {
  79. if (!$data) {
  80. $data = array();
  81. }
  82. $type = $this->getType($type, $currency);
  83. $order_id = $this->createOrder($uid, $this->name, $product_name, $amount, $type['currency'], $type['name']);
  84. $method = $type['method'];
  85. $param = array();
  86. if ($type['currency']) {
  87. $param['amount'] = $amount;
  88. $param['currency'] = $type['currency'];
  89. }
  90. $param = $this->param($order_id, $type['command'], $type['value'], $param);
  91. $data += $param;
  92. return $this->result($method, $param, $data);
  93. }
  94. /**
  95. * 获取返回数据
  96. *
  97. * @return mixed
  98. */
  99. private function result($method, $param, $data)
  100. {
  101. $form = $this->form($param);
  102. return array('form' => $form, 'url' => $this->url, 'param' => $data, 'method' => $method);
  103. }
  104. /**
  105. * 通知回调
  106. *
  107. * @return mixed
  108. */
  109. public function notify($param)
  110. {
  111. if (empty($param)) {
  112. Dever::alert('invalid_parameters');
  113. }
  114. $responseSignature = $param['signature'];
  115. $order_id = $param['merchant_reference'];
  116. unset($param['l']);
  117. unset($param['signature']);
  118. unset($param['integration_type']);
  119. unset($param['product_name']);
  120. unset($param['order_id']);
  121. $amount = $param['amount'];
  122. if (isset($param['card_number']) && $param['card_number']) {
  123. unset($param['amount']);
  124. }
  125. $signature = $this->signature($this->config['response_phrase'], $param);
  126. if ($signature != $responseSignature) {
  127. $this->updateOrder($param['merchant_reference'], $amount, 'invalid_signature');
  128. }
  129. if (substr($param['response_code'], 2) != '000') {
  130. $this->updateOrder($param['merchant_reference'], $amount, $param['response_message']);
  131. }
  132. return true;
  133. }
  134. /**
  135. * 生成基本参数
  136. *
  137. * @return mixed
  138. */
  139. private function param($order_id, $command, $payment_option, $param = array())
  140. {
  141. $param['access_code'] = $this->config['access_code'];
  142. $param['merchant_identifier'] = $this->config['merchant_id'];
  143. $param['merchant_reference'] = $order_id;
  144. $param['language'] = $this->language;
  145. if ($payment_option) {
  146. $param['payment_option'] = $payment_option;
  147. }
  148. # AUTHORIZATION(授权)、PURCHASE(购买) TOKENIZATION CHECK_STATUS
  149. if ($command == 'TOKENIZATION') {
  150. $param['service_command'] = $command;
  151. } else {
  152. $param['command'] = $command;
  153. }
  154. $param['return_url'] = Dever::url('api.notify?order_id=' . $order_id, 'payment');
  155. $param['signature'] = $this->signature($this->config['request_phrase'], $param);
  156. return $param;
  157. }
  158. public function form($data)
  159. {
  160. $form = '<form style="display:none" name="sg-form" id="sg-form" method="post" action="' . $this->url . '" targets="f1"><iframe style="display:none;" id="f1" name="f1"></iframe><input type="hidden" name="function" id="function" value="SG.notify"/>';
  161. foreach ($data as $k => $v) {
  162. $form .= '<input type="hidden" name="' . $k . '" value="' . $v . '">';
  163. }
  164. $form .= '<input type="submit" id="submit">';
  165. return $form;
  166. }
  167. /**
  168. * signature
  169. *
  170. * @return mixed
  171. */
  172. private function signature($phrase, $request)
  173. {
  174. ksort($request);
  175. $signature_string = '';
  176. foreach ($request as $k => $v) {
  177. $signature_string .= $k . '=' . $v;
  178. }
  179. $signature_string = $phrase . $signature_string . $phrase;
  180. return hash('sha256', $signature_string);
  181. }
  182. }