123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335 |
- <?php
- namespace Payment\Lib;
- use Dever;
- class Payfort extends Core
- {
- private $config = array();
- private $language = 'en';
- private $url = 'https://checkout.payfort.com/FortAPI/paymentPage';
- private $gatewayUrl = 'https://paymentservices.payfort.com/FortAPI/paymentApi';
- public function __construct($name, $config)
- {
- $this->name = $name;
- $this->config = $config;
- }
- private function getType($type, $currency = '')
- {
- if ($type < 5 && $currency == 'SAR') {
- $type = 4;
- }
- $name = $value = $method = $command = '';
- switch ($type) {
- case 1:
- # 目前不支持
- $name = 'Pay with credit cards (Redirection)';
- $method = 'redirection';
- $currency = '';
- $command = 'PURCHASE';
- break;
- case 2:
- $name = 'Pay with installments (Redirection)';
- $method = 'redirection';
- $currency = 'USD';
- $command = 'PURCHASE';
- break;
- case 3:
- $name = 'Pay with NAPS';
- $value = 'NAPS';
- $currency = 'NAPS';
- $command = 'AUTHORIZATION';
- $method = 'redirection';
- break;
- case 4:
- $name = 'Pay with SADAD';
- $value = 'SADAD';
- $currency = 'SAR';
- $method = 'redirection';
- $command = 'AUTHORIZATION';
- break;
- case 11:
- $name = 'Pay with credit cards (Merchant Page)';
- $method = 'page';
- $currency = '';
- $command = 'TOKENIZATION';
- break;
- case 12:
- $name = 'Pay with installments (Merchant Page)';
- $method = 'page';
- $currency = '';
- $command = 'TOKENIZATION';
- break;
- case 21:
- $name = 'Pay with credit cards (Merchant Page 2.0)';
- $method = 'page_v2';
- $currency = '';
- $command = 'TOKENIZATION';
- break;
- }
- $currency = strtoupper($currency);
- return array
- (
- 'id' => $type,
- 'name' => $name,
- 'value' => $value,
- 'method' => $method,
- 'currency' => $currency,
- 'command' => $command,
- );
- }
- /**
- * 获取统一下单的基本信息
- */
- public function request($type, $uid, $account, $product_name, $amount, $currency, $data = array())
- {
- if (!$data) {
- $data = array();
- }
- $type = $this->getType($type, $currency);
- $order_id = $this->createOrder($uid, $this->name, $product_name, $amount, $type['currency'], $type['id'], $type['name']);
- $method = $type['method'];
- $param = array();
- if ($type['id'] == 3) {
- $param['order_description'] = $product_name;
- }
- $param = $this->param($order_id, $amount, $type['currency'], $type['command'], $type['value'], $type['id'], $param);
- $data += $param;
- return $this->result($method, $param, $data);
- }
- /**
- * 生成基本参数
- *
- * @return mixed
- */
- private function param($order_id, $amount, $currency, $command, $payment_option, $type, $param = array())
- {
- if ($type == 2 || $type == 12) {
- $param['installments'] = 'STANDALONE';
- }
- if ($type == 12 && isset($param['plan_code'])) {
- $param['installments'] = 'YES';
- $command = 'PURCHASE';
- }
- if ($currency) {
- $param['amount'] = $this->convertFortAmount($amount, $currency);
- $param['currency'] = $currency;
- }
- $param['access_code'] = $this->config['access_code'];
- $param['merchant_identifier'] = $this->config['merchant_id'];
- $param['merchant_reference'] = $order_id;
- $param['language'] = $this->language;
- if ($payment_option) {
- $param['payment_option'] = $payment_option;
- }
- # AUTHORIZATION(授权)、PURCHASE(购买) TOKENIZATION CHECK_STATUS
- if ($command == 'TOKENIZATION') {
- $param['service_command'] = $command;
- } else {
- $param['command'] = $command;
- }
-
- $param['return_url'] = Dever::url('api.notify?order_id=' . $order_id, 'payment');
- $param['signature'] = $this->signature($this->config['request_phrase'], $param);
- return $param;
- }
- /**
- * 获取返回数据
- *
- * @return mixed
- */
- private function result($method, $param, $data)
- {
- $form = $this->form($param);
- return array('form' => $form, 'url' => $this->url, 'param' => $data, 'method' => $method);
- }
- /**
- * 通知回调
- *
- * @return mixed
- */
- public function notify($param)
- {
- if (empty($param)) {
- return $this->out('invalid_parameters');
- }
- if (!isset($param['signature'])) {
- return $this->out('invalid_parameters');
- }
- $post = $param;
- $responseSignature = $param['signature'];
- $order_id = $param['merchant_reference'];
- unset($param['l']);
- if (isset($param['3ds'])) {
- unset($param['3ds']);
- }
- if (isset($param['product_name'])) {
- unset($param['product_name']);
- }
- if (isset($param['integration_type'])) {
- unset($param['integration_type']);
- }
- if (isset($param['signature'])) {
- unset($param['signature']);
- }
- if (isset($param['order_id'])) {
- unset($param['order_id']);
- }
- if (isset($param['type'])) {
- unset($param['type']);
- }
- if (isset($param['currency']) && $param['currency']) {
- $param['amount'] = $this->convertFortAmount($param['amount'], $param['currency']);
- }
-
- $amount = $param['amount'];
- if (isset($param['card_number']) && $param['card_number']) {
- unset($param['amount']);
- }
- $signature = $this->signature($this->config['response_phrase'], $param);
- if ($signature != $responseSignature) {
- return $this->updateOrder($param['merchant_reference'], $amount, 'invalid_signature');
- }
-
- if (substr($param['response_code'], 2) != '000') {
- return $this->updateOrder($param['merchant_reference'], $amount, $param['response_message']);
- }
- if (isset($param['card_number']) && $param['card_number']) {
- return $this->pageNotify($post);
- }
- return $this->out('ok');
- }
- /**
- * merchantPageNotifyFort
- *
- * @return mixed
- */
- private function pageNotify($param)
- {
- $type = $this->getType($param['type']);
- $method = $type['method'];
- $post = array();
- $post['customer_ip'] = $_SERVER['REMOTE_ADDR'];
- if (isset($param['token_name'])) {
- $post['token_name'] = $param['token_name'];
- }
- if(isset($param['3ds']) && $param['3ds'] == 'no') {
- $post['check_3ds'] = 'NO';
- }
- if (!$type['currency']) {
- $type['currency'] = 'USD';
- }
- $type['command'] = 'AUTHORIZATION';
- $post = $this->param($param['order_id'], $param['amount'], $type['currency'], $type['command'], $type['value'], $type['id'], $post);
- print_r($post);die;
- $result = Dever::curl($this->gatewayUrl, $post, 'post');
- return $this->notify($result);
- }
- public function form($data)
- {
- $form = '<form style="display:none" name="sg-form" id="sg-form" method="post" action="' . $this->url . '">';
- foreach ($data as $k => $v) {
- $form .= '<input type="hidden" name="' . $k . '" value="' . $v . '">';
- }
- $form .= '<input type="submit" id="submit">';
- return $form;
- }
- /**
- * signature
- *
- * @return mixed
- */
- private function signature($phrase, $request)
- {
- ksort($request);
- $signature_string = '';
- foreach ($request as $k => $v) {
- $signature_string .= $k . '=' . $v;
- }
- $signature_string = $phrase . $signature_string . $phrase;
- return hash('sha256', $signature_string);
- }
- /**
- * Convert Amount with dicemal points
- * @param decimal $amount
- * @param string $currencyCode
- * @return decimal
- */
- private function convertFortAmount($amount, $currencyCode)
- {
- $new_amount = 0;
- $total = $amount;
- $decimalPoints = $this->getCurrencyDecimalPoints($currencyCode);
- $new_amount = round($total, $decimalPoints) * (pow(10, $decimalPoints));
- return $new_amount;
- }
- private function castAmountFromFort($amount, $currencyCode)
- {
- $decimalPoints = $this->getCurrencyDecimalPoints($currencyCode);
- //return $amount / (pow(10, $decimalPoints));
- $new_amount = round($amount, $decimalPoints) / (pow(10, $decimalPoints));
- return $new_amount;
- }
- private function getCurrencyDecimalPoints($currency)
- {
- $decimalPoint = 2;
- $arrCurrencies = array(
- 'JOD' => 3,
- 'KWD' => 3,
- 'OMR' => 3,
- 'TND' => 3,
- 'BHD' => 3,
- 'LYD' => 3,
- 'IQD' => 3,
- 'USD' => 0,
- );
- if (isset($arrCurrencies[$currency])) {
- $decimalPoint = $arrCurrencies[$currency];
- }
- return $decimalPoint;
- }
- }
|