• php 对接国外支付 ipay88支付


    ipay88支付

    近期接了一个国外的项目,客户指定要这种支付,就搞搞呗,其实流程和思路都是差不多的,往下看

    他的流程其实非常简单  下面的流程仔细看看,看懂了就会了

               1 首先我们需要先获取下单所需要的参数(这个需要去ipay88官网去申请),

                就是下面main.php里面的一些参数merchantCode,merchantKey

               2 参数完整之后我们要做的就是验证签名了(下面有我的验证签名的方式,支付类文件,拿着用就好)

               3 当我们在页面实际付款的时候,我们需要使用一个form表单 post方式执行我们的操作,

                我们需要将签名所需要的参数都以form表单的形式提交到ipay88给我们提供的地址,会自动跳转到支付页(成功唤醒就代表对接成功了)

              4 注意form表单提交的时候,参数一定要完整

              5 测试的时候,ipay88只支持信用卡支付(visa,master),并且支付金额只能为1元

    yii-iPay88 API将帮助您为应用程序实现iPay88付款网关。此API中包含以下操作

    • 正常付款
    • 定期付款
    • 定期付款终止
    • 后端通知  

    认证方式

    yii-iPay88 API使用十六进制和base64编码技术来创建唯一签名。然后,此签名将用于客户端的每个请求以及iPay88服务器发送的每个响应。

    基本上,此签名基于商户代码,商户密钥,付款金额,货币代码,refno。等。所有API请求都必须通过HTTPS进行。

    用法

    main.php

    'components' => array(
    ....
    'ipay' => array(
            'class'=>'Ipay',    
            'merchantCode'=>'<<merchantCode>>',
            'merchantKey'=>'<<merchantKey>>',
            'currencyCode'=>'MYR', // length 5                        
            'responseUrl'=>'http://<<hostname>>/ipay/response',
            'backendUrl'=>'http://<<hostname>>/ipaybackend/response',
            'requeryUrl'=>'https://www.mobile88.com/epayment/enquiry.asp',
            'paymentUrl'=>'https://www.mobile88.com/epayment/entry.asp',
            'recurringUrlSubscription'=>'https://www.ipay88.com/recurringpayment/webservice/RecurringPayment.asmx/Subscription',
            'recurringUrlTermination'=>'https://www.ipay88.com/recurringpayment/webservice/RecurringPayment.asmx/Termination'
            
        ),
    ....
    )

    一个虚拟控制器,演示此组件用于iPay88正常付款的用法并获得该响应,这个也就是你传给支付类文件的参数方法

    IpayController.php

    class IpayController extends Controller {
    
        const TRANSACTION_TYPE_PAYMENT = 'payment';
        const TRANSACTION_TYPE_RECURRING_SUBSCRIPTION = 'recurring_subscription';
        const TRANSACTION_TYPE_RECURRING_TERMINATION = 'recurring_termination';
    
        /*
         * iPay88 normal payment Method
         */
        public function actionPayment() {
    
            // Unique merchant transaction number / Order ID (Retry for same RefNo only valid for 30 mins). (length 20)
            $paymentParams['RefNo'] = 'TEST123';
    
            // (Optional) (int)
            $paymentParams['PaymentId'] = '2';
    
            // Payment amount with two decimals.
            $paymentParams['Amount'] = '1.00';
    
            // Product description. (length 100)
            $paymentParams['ProdDesc'] = 'This is a test product';
    
            // Customer name. (length 100)
            $paymentParams['UserName'] = 'Abc';
    
            // Customer email.  (length 100)
            $paymentParams['UserEmail'] = 'abc@xyz.com';
    
            // Customer contact.  (length 20)
            $paymentParams['UserContact'] = '*************';
    
            // (Optional) Merchant remarks. (length 100)
            $paymentParams['Remark'] = 'Here is the description';
    
            $paymentFields = Yii::app()->ipay->getPaymentFields($paymentParams, self::TRANSACTION_TYPE_PAYMENT);
            $transactionUrl = Yii::app()->ipay->getTransactionUrl(self::TRANSACTION_TYPE_PAYMENT);
            $this->render('Payment', array(
                'paymentFields' => $paymentFields,
                'transactionUrl' => $transactionUrl
            ));
        }
            
    }

    /Ipay.php    这个就是你的支付类文件了,用的时候改一下里面的参数就可以,因为这个是基于yii框架的,你可以改一下里面的有些参数,或者删除就好

    class Ipay extends CApplicationComponent {
    
        /**
         * Normal iPay88 payment method
         */
        const TRANSACTION_TYPE_PAYMENT = 'payment';
    
        /**
         * Normal iPay88 recurring payment subscription
         */
        const TRANSACTION_TYPE_RECURRING_SUBSCRIPTION = 'recurring_subscription';
    
        /**
         * Normal iPay88 recurring payment termination
         */
        const TRANSACTION_TYPE_RECURRING_TERMINATION = 'recurring_termination';
    
        /**
         * Merchant code assigned by iPay88
         */
        public $merchantCode;
        
        /**
         * Merchant Key assigned by iPay88
         */
        public $merchantKey;
        
        /**
         * Currency Code max length 5
         */
        public $currencyCode;
        
        /**
         * Merchant code assigned by iPay88
         */    
        public $responseUrl;
        
        /*
         * Response Url or Return Url after payment
         */
        public $paymentUrl;
        
        /*
         * Backend Url or Notify Url after payment (Send response by iPay88 server)
         */
        public $backendUrl;
        
        /*
         * Requery from iPay88 server regarding bill details
         */
        public $requeryUrl;
        
         /*
         * ipay88 Recurring Payment Url
         */
        public $recurringUrlSubscription;
        
         /*
         * ipay88 Recurring Payment Termination Url
         */
        public $recurringUrlTermination;
        
        
        /*
         * Details to be sent to IPay88 for payment request.
         */    
        private $paymentRequest = array(
            'MerchantCode', // Merchant code assigned by iPay88. (length 20)
            'PaymentId', // (Optional) (int)
            'RefNo', // Unique merchant transaction number / Order ID (Retry for same RefNo only valid for 30 mins). (length 20)
            'Amount', // Payment amount with two decimals.
            'Currency', // (length 5)
            'ProdDesc', // Product description. (length 100)
            'UserName', // Customer name. (length 100)
            'UserEmail', // Customer email.  (length 100)
            'UserContact', // Customer contact.  (length 20)
            'Remark', // (Optional) Merchant remarks. (length 100)
            'Lang', // (Optional) Encoding type:- ISO-8859-1 (English), UTF-8 (Unicode), GB2312 (Chinese Simplified), GD18030 (Chinese Simplified), BIG5 (Chinese Traditional)
            'Signature',
            'ResponseURL',
            'BackendURL',
        );
    
        
        /*
         * Details to be sent to iPay88 for recurring subscription payment request.
         */    
        private $recurringSubscriptionRequest = array(
            'MerchantCode', // Merchant code assigned by iPay88. (length 20)
            'RefNo', // Unique merchant transaction number / Order ID. (length 20)
            'FirstPaymentDate', // (ddmmyyyy)
            'Currency', // MYR only. (length 5)
            'Amount', // Payment amount with two decimals.
            'NumberOfPayments', // (int)
            'Frequency', // Frequency type; 1 - Monthly, 2 - Quarterly, 3 - Half-Yearly, 4 - Yearly. (int)
            'Desc', // Product description. (length 100)
            'CC_Name', // Name printed on credit card. (length 100)
            'CC_PAN', // 16-digit credit card number (Visa/Mastercard). (length 16)
            'CC_CVC', // 3-digit verification code behind credit card. (length 3)
            'CC_ExpiryDate', // Credit card expiry date. (mmyyyy)
            'CC_Country', // Credit card issuing country. (length 100)
            'CC_Bank', // Credit card issuing bank. (length 100)
            'CC_Ic', // Credit card holder IC / Passport number. (length 50)
            'CC_Email', // Credit card holder email address. (length 255)
            'CC_Phone', // Credit card phone number. (length 100)
            'CC_Remark', // (Optional) Remarks. (varchar 100)
            'P_Name', // Subscriber name as printed in IC / Passport. (length 100)
            'P_Email', // Subscriber email address. (length 255)
            'P_Phone', // Subscriber phone number. (length 100)
            'P_Addrl1', // Subscriber address line 1. (length 100)
            'P_Addrl2', // (Optional) Subscriber address line 2. (length 100)
            'P_City', // Subscriber city. (length 100)
            'P_State', // Subscriber state. (length 100)
            'P_Zip', // Subscriber zip code. (length 100)
            'P_Country', // Subscriber country. (varchar 100)
            'BackendURL', // Payment backend response page. (length 255)
            'Signature', // SHA1 signature. (length 100)
        );
        
        
        /*
         * Get required payment fields
         */
        public function getPaymentFields($reqParams = null, $paymentType) {
            $retnParams = array();
            try {
                if (isset($reqParams) && (count($reqParams) > 0)) {
    
                    if (isset($paymentType) && $paymentType != "") {
                        $paymentType = strtolower(trim($paymentType));
                        switch ($paymentType) {
                            case 'payment':
                                $retnParams = $this->__getPaymentField($reqParams, $paymentType);
                                break;
                            case 'recurring_subscription':
                                $retnParams = $this->__getRecurringSubscriptionField($reqParams, $paymentType);
                                break;
                            case 'recurring_termination':
                                $retnParams = $this->__getRecurringTerminationField($reqParams, $paymentType);
                                break;
                        }
                    } else {
                        throw new Exception("Ipay: Payment method missing");
                    }
                } else {
                    throw new Exception("Ipay: Required Parameters missing");
                }
            } catch (Exception $e) {
                Yii::log($e->getMessage(), CLogger::LEVEL_ERROR);
            }
            return $retnParams;
        }
    
        /*
         * Code for hex2bin 
         */
        public function _hex2bin($hexSource) {
            $bin = '';
            for ($i = 0; $i < strlen($hexSource); $i = $i + 2) {
                $bin .= chr(hexdec(substr($hexSource, $i, 2)));
            }
            return $bin;
        }
    
        /*
         * Get payment fields for normal payment fields 
         */
        public function __getPaymentField($reqParams, $paymentType) {
            $retnParams = array();
            foreach ($this->paymentRequest as $pymtKey) {
                if (isset($reqParams[$pymtKey])) {
                    $retnParams[$pymtKey] = $reqParams[$pymtKey];
                } else {
    
                    switch ($pymtKey) {
                        case 'MerchantCode':
                            $retnParams[$pymtKey] = $this->merchantCode;
                            break;
                        case 'Currency':
                            $retnParams[$pymtKey] = $this->currencyCode;
                            break;
                        case 'Lang':
                            $retnParams[$pymtKey] = 'UTF-8'; //(Optional) Encoding type:- ISO-8859-1 (English), UTF-8 (Unicode), GB2312 (Chinese Simplified), GD18030 (Chinese Simplified), BIG5 (Chinese Traditional)
                            break;
                        case 'Signature':
                            $retnParams[$pymtKey] = $this->__createSignature($retnParams, $paymentType); // SHA1 signature.
                            break;
                        case 'ResponseURL':
                            $retnParams[$pymtKey] = $this->responseUrl; // (Optional) Payment response page.
                            break;
                        case 'BackendURL':
                            $retnParams[$pymtKey] = $this->backendUrl; // (Optional) BackendURL but should security purpose
                            break;
                    }
                }
            }
    
            return $retnParams;
        }
        
        /*
         * Get payment fields for recurring payment
         */
        public function __getRecurringSubscriptionField($reqParams, $paymentType) {
            $retnParams = array();
            foreach ($this->recurringSubscriptionRequest as $pymtKey) {
                if (isset($reqParams[$pymtKey])) {
                    $retnParams[$pymtKey] = $reqParams[$pymtKey];
                } else {
    
                    switch ($pymtKey) {
                        case 'MerchantCode':
                            $retnParams[$pymtKey] = $this->merchantCode;
                            break;
                        case 'Currency':
                            $retnParams[$pymtKey] = $this->currencyCode;
                            break;
                        case 'Lang':
                            $retnParams[$pymtKey] = 'UTF-8'; //(Optional) Encoding type:- ISO-8859-1 (English), UTF-8 (Unicode), GB2312 (Chinese Simplified), GD18030 (Chinese Simplified), BIG5 (Chinese Traditional)
                            break;
                        case 'Signature':
                            $retnParams[$pymtKey] = $this->__createSignature($retnParams, $paymentType); // SHA1 signature.
                            break;
                        case 'ResponseURL':
                            $retnParams[$pymtKey] = $this->responseUrl; // (Optional) Payment response page.
                            break;
                        case 'BackendURL':
                            $retnParams[$pymtKey] = $this->backendUrl; // (Optional) BackendURL but should security purpose
                            break;
                    }
                }
            }
    
            return $retnParams;
        }
    
        
        
        /*
         * Get payment fields for recurring payment termination
         */
        public function __getRecurringTerminationField($reqParams, $paymentType) {
            $retnParams = array();
            foreach ($this->recurringSubscriptionRequest as $pymtKey) {
                if (isset($reqParams[$pymtKey])) {
                    $retnParams[$pymtKey] = $reqParams[$pymtKey];
                } else {
    
                    switch ($pymtKey) {
                        case 'MerchantCode':
                            $retnParams[$pymtKey] = $this->merchantCode;
                            break;
                    }
                }
            }
    
            return $retnParams;
        }
        
        /*
         * Create signature for payment
         */
        public function __createSignature($signatureParams, $paymentType) {
            //echo "<pre>";
            //print_r($signatureParams);
            $signature = '';
            if (isset($signatureParams)) {
                $_signatureParams = array();
                if ($paymentType == self::TRANSACTION_TYPE_PAYMENT) {
                    $_signatureParams = array('MerchantCode', 'RefNo', 'Amount', 'Currency');
                } else if ($paymentType == self::TRANSACTION_TYPE_RECURRING_SUBSCRIPTION) {
                    $_signatureParams = array('MerchantCode', 'RefNo', 'FirstPaymentDate', 'Currency', 'Amount', 'NumberOfPayments', 'Frequency', 'CC_PAN');
                } else if ($paymentType == self::TRANSACTION_TYPE_RECURRING_TERMINATION) {
                    $_signatureParams = array('MerchantCode', 'RefNo');
                }
    
    
                foreach ($_signatureParams as $val) {
                    if (!isset($signatureParams[$val])) {
                        throw new Exception("Ipay: Missing required parameters for signature.");
                        return false;
                    }
                }
            }
    
            // Make sure the order is correct.
            if ($paymentType == self::TRANSACTION_TYPE_PAYMENT) {
                $signature .= $this->merchantKey;
                $signature .= $signatureParams['MerchantCode'];
                $signature .= $signatureParams['PaymentId'];
                $signature .= $signatureParams['RefNo'];
                $signature .= preg_replace("/[^d]+/", "", $signatureParams['Amount']);
                $signature .= $signatureParams['Currency'];
            } else if ($paymentType == self::TRANSACTION_TYPE_RECURRING_SUBSCRIPTION) {
                $signature .= $signatureParams['MerchantCode'];
                $signature .= $this->merchantKey;
                $signature .= $signatureParams['RefNo'];
                $signature .= $signatureParams['FirstPaymentDate'];
                $signature .= $signatureParams['Currency'];
                $signature .= $signatureParams['Amount'];
                $signature .= $signatureParams['NumberOfPayments'];
                $signature .= $signatureParams['Frequency'];
                $signature .= $signatureParams['CC_PAN'];
            } else if ($paymentType == self::TRANSACTION_TYPE_RECURRING_TERMINATION) {
                $signature .= $signatureParams['MerchantCode'];
                $signature .= $this->merchantKey;
                $signature .= $signatureParams['RefNo'];
            }
    
    
            // Hash the signature.
            return $signature = base64_encode($this->_hex2bin(sha1($signature)));
        }
    
        /*
         * Get url for respective payment redirection url
         */
        public function getTransactionUrl($paymentType) {
            if ($paymentType == self::TRANSACTION_TYPE_PAYMENT) {
                return $this->paymentUrl;
            } else if ($paymentType == self::TRANSACTION_TYPE_RECURRING_SUBSCRIPTION) {
                return $this->recurringUrlSubscription;
            } else if ($paymentType == self::TRANSACTION_TYPE_RECURRING_TERMINATION) {
                return $this->recurringUrlTermination;
            }
        }
    
    
        /*
         * iPay88 payment signature validation
         */
        public function checkiPay88Signature($reqParams) {
            $status = 'fail';
            try {
                if (isset($reqParams) && count($reqParams) > 0) {
                    $orginalKey = $this->merchantKey . $this->merchantCode;
                    if (isset($reqParams['RefNo'])) {
                        $orginalKey .=$reqParams['RefNo'];
                    }
    
                    if (isset($reqParams['Amount'])) {
                        $orginalKey .=preg_replace("/[^d]+/", "", $reqParams['Amount']);
                    }
                    $orginalKey .= $this->currencyCode;
                    if (isset($reqParams['Status'])) {
                        $orginalKey .=$reqParams['Status'];
                    }
    
                    $orginalKeyGen = base64_encode($this->_hex2bin(sha1($orginalKey)));
                    $returnKey = $this->merchantKey;
                    if (isset($reqParams['MerchantCode'])) {
                        $returnKey .=$reqParams['MerchantCode'];
                    }
    
    
                    if (isset($reqParams['RefNo'])) {
                        $returnKey .=$reqParams['RefNo'];
                    }
                    if (isset($reqParams['Amount'])) {
                        $returnKey .=preg_replace("/[^d]+/", "", $reqParams['Amount']);
                    }
                    if (isset($reqParams['Currency'])) {
                        $returnKey .=$reqParams['Currency'];
                    }
                    if (isset($reqParams['Status'])) {
                        $returnKey .=$reqParams['Status'];
                    }
    
    
                    $returnKeyGen = base64_encode($this->_hex2bin(sha1($returnKey)));
                    if ($orginalKeyGen === $returnKeyGen) {
                        $status = 'success';
                    }
                } else {
                    throw new Exception("Ipay::checkiPay88Signature: Params missing");
                }
            } catch (exception $e) {
                Yii::log($e->getMessage(), CLogger::LEVEL_ERROR);
            }
    
            return $status;
        }
    
        /*
         * Curl hit to get bill deyails 
         */
        public function requeryPayment($rawPostData) {
            try {
                $result = '';
                if (is_callable('curl_init')) {
                    if (isset($rawPostData) && $rawPostData != "") {
                        $ch = curl_init();
                        $url = $this->requeryUrl . '?' . $rawPostData;
                        curl_setopt($ch, CURLOPT_URL, $url);
                        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
                        $result = curl_exec($ch);
                        curl_close($ch);
                    } else {
                        throw new Exception("Ipay::requeryPayment: No request string");
                    }
                } else {
                    throw new Exception("Ipay::requeryPayment: Curl not enabled");
                }
            } catch (exception $e) {
                Yii::log($e->getMessage(), CLogger::LEVEL_ERROR);
            }
    
            return $result;
        }
    
    }

    views / ipay / payment.php   这个相当于你的回调地址了,下单成功后跳转到这里执行你想要的操作

    <?php
    
    $rawPostData = file_get_contents('php://input');
    $resultData = array();
    if (strlen($rawPostData) > 0) {
        $rawPostArray = explode('&', $rawPostData);
        foreach ($rawPostArray as $keyval) {
            $keyval = explode('=', $keyval);
            if (count($keyval) == 2)
                $resultData[$keyval[0]] = urldecode($keyval[1]);
        }
    }

    这个就是模拟的form表单了,参照这个提交就没问题了

    <
    FORM method="post" name="ePayment" action="https://payment.ipay88.com.my/ePayment/entry.asp"> <INPUT type="hidden" name="MerchantCode" value="M00003"> <INPUT type="hidden" name="PaymentId" value="2"> <INPUT type="hidden" name="RefNo" value="A00000001"> <INPUT type="hidden" name="Amount" value="1.00"> <INPUT type="hidden" name="Currency" value="MYR"> <INPUT type="hidden" name="ProdDesc" value="Photo Print"> <INPUT type="hidden" name="UserName" value="John Tan"> <INPUT type="hidden" name="UserEmail" value="john@hotmail.com"> <INPUT type="hidden" name="UserContact" value="0126500100"> <INPUT type="hidden" name="Remark" value="gfdfgd"> <INPUT type="hidden" name="Lang" value="UTF-8"> <INPUT type="hidden" name="SignatureType" value="SHA256"> <INPUT type="hidden" name="Signature" value="b81af9c4048b0f6c447129f0f5c0eec8d67cbe19eec26f2cdaba5df4f4dc5a28"> <INPUT type="hidden" name="ResponseURL" value="http://gx.oeob.net/mobile/respons_ipay.php"> <INPUT type="hidden" name="BackendURL" value="http://gx.oeob.net/mobile/respons_ipay.php"> <INPUT type="submit" value="Proceed with Payment" name="Submit"> </FORM>

    如果有不明白的地方,评论给我,或者发我邮箱2653293344@qq.com

  • 相关阅读:
    关于Spring MVC跨域
    Linux(Debian) 上安装tomcat并注册服务开机自启动
    fastjson SerializerFeature详解
    Mysql group_concat函数被截断的问题
    eclipse中show whitespace characters显示代码空格,TAB,回车 导致代码乱恶心
    Oracle数据库之动态SQL
    tomcat日志报Invalid message received with signature的解决办法
    用HttpClient发送HTTPS请求报SSLException: Certificate for <域名> doesn't match any of the subject alternative names问题的解决
    高可用集群架构的演进
    database disk image is malformed
  • 原文地址:https://www.cnblogs.com/bkhdd/p/12215110.html
Copyright © 2020-2023  润新知