php - 使用 codeigniter 的 payfast 支付网关集成

标签 php codeigniter response payment-gateway payment

我是 Codeigniter 中 PayFast 支付网关集成的新手。

这是我生成表单的代码:

表单

<form action="https://sandbox.payfast.co.za/eng/process" method="post">
    <input id="merchant_id" name="merchant_id" value="ID" type="hidden">
    <input id="merchant_key" name="merchant_key" value="KEY" type="hidden">
    <input id="return_url" name="return_url" value="RETURNURL" type="hidden">
    <input id="cancel_url" name="cancel_url" value="CANCELURL" type="hidden">
    <input id="notify_url" name="notify_url" value="http://website.com/deal/itn" type="hidden">
    <input id="name_first" name="name_first" value="test" type="hidden">
    <input id="name_last" name="name_last" value="test1" type="hidden">
    <input id="email_address" name="email_address" value="test@gmail.com" type="hidden">
    <input id="m_payment_id" name="m_payment_id" value="TRN1481493600" type="hidden">
    <input id="amount" name="amount" value="930" type="hidden">
    <input id="item_name" name="item_name" value="package" type="hidden">
    <input id="item_description" name="item_description" value="package" type="hidden">
    <input id="payment_method" name="payment_method" value="cc" type="hidden">
    <input id="signature" name="signature" value="a8836e97dfdbeb6116747d7c1130f4ff" type="hidden">
</form>

Controller

<?php
function itn()
{
    define( 'PAYFAST_SERVER', 'TEST' );
    define( 'USER_AGENT', 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)' );
    define( 'PF_ERR_AMOUNT_MISMATCH', 'Amount mismatch' );
    define( 'PF_ERR_BAD_SOURCE_IP', 'Bad source IP address' );
    define( 'PF_ERR_CONNECT_FAILED', 'Failed to connect to PayFast' );
    define( 'PF_ERR_BAD_ACCESS', 'Bad access of page' );
    define( 'PF_ERR_INVALID_SIGNATURE', 'Security signature mismatch' );
    define( 'PF_ERR_CURL_ERROR', 'An error occurred executing cURL' );
    define( 'PF_ERR_INVALID_DATA', 'The data received is invalid' );
    define( 'PF_ERR_UKNOWN', 'Unkown error occurred' );
    define( 'PF_MSG_OK', 'Payment was successful' );
    define( 'PF_MSG_FAILED', 'Payment has failed' );
    header( 'HTTP/1.0 200 OK' );
    flush();
    $pfError = false;
    $pfErrMsg = '';
    $filename = 'notify.txt';
    $output = '';
    $pfParamString = '';
    $pfHost = ( PAYFAST_SERVER == 'LIVE' ) ?
    'www.payfast.co.za' : 'sandbox.payfast.co.za';
    $pfData = [];

    if( !$pfError )
    {
        $output = $_POST;
        foreach( $_POST as $key => $val )
            $pfData[$key] = stripslashes( $val );

        foreach( $pfData as $key => $val )
        {
            if( $key != 'signature' )
                $pfParamString .= $key .'='. urlencode( $val ) .'&';
        }

        $pfParamString = substr( $pfParamString, 0, -1 );
        $pfTempParamString = $pfParamString;

        $passPhrase = '123456789101112';
        if( !empty( $passPhrase ) )
        {
            $pfTempParamString .= '&passphrase='.urlencode( $passPhrase );
        }
        $signature = md5( $pfTempParamString );

        $result = ( $_POST['signature'] == $signature );

        $output .= "Security Signature:\n\n";
        $output .= "- posted     = ". $_POST['signature'] ."\n";
        $output .= "- calculated = ". $signature ."\n";
        $output .= "- result     = ". ( $result ? 'SUCCESS' : 'FAILURE' ) ."\n";
        echo "<pre>";
        var_dump($output);
        echo "</pre>";
        die();
    }

    if( !$pfError )
    {
        $validHosts = array(
            'www.payfast.co.za',
            'sandbox.payfast.co.za',
            'w1w.payfast.co.za',
            'w2w.payfast.co.za',
            );

        $validIps = array();

        foreach( $validHosts as $pfHostname )
        {
            $ips = gethostbynamel( $pfHostname );

            if( $ips !== false )
                $validIps = array_merge( $validIps, $ips );
        }
        $validIps = array_unique( $validIps );

        if( !in_array( $_SERVER['REMOTE_ADDR'], $validIps ) )
        {
            $pfError = true;
            $pfErrMsg = PF_ERR_BAD_SOURCE_IP;
        }
    }

    if( !$pfError )
    {
        if( function_exists( 'curl_init' ) )
        {
            $output .= "\n\nUsing cURL\n\n";
            $ch = curl_init();
            $curlOpts = array(
                CURLOPT_USERAGENT => USER_AGENT,
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_HEADER => false,
                CURLOPT_SSL_VERIFYHOST => 2,
                CURLOPT_SSL_VERIFYPEER => false,
                CURLOPT_URL => 'https://'. $pfHost . '/eng/query/validate',
                CURLOPT_POST => true,
                CURLOPT_POSTFIELDS => $pfParamString,
                );
            curl_setopt_array( $ch, $curlOpts );
            $res = curl_exec( $ch );
            curl_close( $ch );

            if( $res === false )
            {
                $pfError = true;
                $pfErrMsg = PF_ERR_CURL_ERROR;
            }
        }
        else
        {
            $output .= "\n\nUsing fsockopen\n\n";
            $header = "POST /eng/query/validate HTTP/1.0\r\n";
            $header .= "Host: ". $pfHost ."\r\n";
            $header .= "Content-Type: application/x-www-form-urlencoded\r\n";
            $header .= "Content-Length: " . strlen( $pfParamString ) . "\r\n\r\n";
            $socket = fsockopen( 'ssl://'. $pfHost, 443, $errno, $errstr, 10 );
            fputs( $socket, $header . $pfParamString );
            $res = '';
            $headerDone = false;

            while( !feof( $socket ) )
            {
                $line = fgets( $socket, 1024 );
                if( strcmp( $line, "\r\n" ) == 0 )
                {
                    $headerDone = true;
                }
                else if( $headerDone )
                {
                    $res .= $line;
                }
            }
        }
    }

    if( !$pfError )
    {
        $lines = explode( "\n", $res );
        $output .= "\n\nValidate response from server:\n\n";
        foreach( $lines as $line )
            $output .= $line ."\n";
    }

    if( !$pfError )
    {
        $result = trim( $lines[0] );
        $output .= "\nResult = ". $result;

        if( strcmp( $result, 'VALID' ) == 0 )
        {

        }
        else
        {
            $pfError = true;
            $pfErrMsg = PF_ERR_INVALID_DATA;
        }
    }

    if( $pfError )
    {
        $output .= "\n\nAn error occurred!";
        $output .= "\nError = ". $pfErrMsg;
    }

    echo "<pre>";
    var_dump($pfError);
    echo "</pre>";
    file_put_contents( $filename, $output );
}
?>

我也遵循代码:PayFast-Payment-Gateway

问题 是,我没有收到任何回复。我怎样才能得到回应?

最佳答案

如果您的 notify_url 没有返回 header 200 响应,您将无法收到 return variables来自 PayFast。

以下是 ITN 代码的最简单示例:

// Notify PayFast that information has been received - this is required
header( 'HTTP/1.0 200 OK' );
flush();

// Posted variables from ITN -the return variables
$pfData = $_POST;

// Update db
switch( $pfData['payment_status'] ){
  case 'COMPLETE':
     // If complete, update your application                   
     break;
  case 'FAILED':                    
     // There was an error, update your application
     break;
  default:
     // If unknown status, do nothing (safest course of action)
     break;
}

看看我对 this question 的回答以供引用。

关于php - 使用 codeigniter 的 payfast 支付网关集成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41095085/

相关文章:

php - 在准备好的语句中执行 SELECT 查询时遇到问题

php - 在 php 中以 root 身份将上传的文件移动到不同的用户主文件夹

php - 如何在 CodeIgniter 表单验证中使用 Bootstrap 错误样式?

php - PHP Codeigniter 中的 URL 重写。

json - MERN 与 axios 堆栈,响应对象返回 html 而不是 json

使用 vim 自动完成 php

php - 面包屑未添加到缓存 View 中

php - 修改并重做 codeigniter 中的最后一个查询

symfony - 从 Controller symfony2 返回图像

php - 使用 php ping 一个 ip,结果只有平均响应时间。