php 对接国外支付 ipay88支付

Posted 寒冬

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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

以上是关于php 对接国外支付 ipay88支付的主要内容,如果未能解决你的问题,请参考以下文章

IPay88支付网关SDK如何实现?

【paypal接口】

怎么对接个人收款支付接口(扫码支付)

PHP对接第三方支付渠道之微信支付v3版本

php对接微信小程序支付

支付宝APP支付(基于Java实现支付宝APP支付)