1

我正在努力工作,而 Omnipay 没有提供太多文档。我已经成功地将它用于其他支付网关,但没有用于 Sagepay。我正在尝试将它集成到 CodeIgniter 中,但可以从其他框架中的示例中工作——我快绝望了!

4

2 回答 2

1

多亏了 github 上的一些巨大帮助(有关线程链接,请参阅我原始帖子中的评论),我现在有一些可行的代码,我将在这里分享,以防将来对其他人有所帮助。

<?php 

use Omnipay\Omnipay;

class PaymentGateway  {

    //live details
    private $live_vendor = 'xxx';
    //test details
    private $test_vendor= 'xxx';

    //payment settings
    private $testMode = true;
    private $api_vendor = '';
    private $gateway = null;

    public function __construct()
    {
        parent::__construct();
        //setup api details for test or live
        if ($this->testMode) :
            $this->api_vendor = $this->test_vendor;
        else :
            $this->api_vendor = $this->live_vendor;
        endif;

        //initialise the payment gateway
        $this->gateway = Omnipay::create('SagePay_Server');
        $this->gateway->setVendor($this->api_vendor);
        $this->gateway->setTestMode($this->testMode);



    }


    public function initiate()
    {

        //get order details
        $orderNo = customFunctionToGetOrderNo(); //get the order number from your system however you store and retrieve it

        $params = array(
            'description'=> 'Online order',
            'currency'=> 'GBP',
            'transactionId'=> $orderNo,
            'amount'=> customFunctionToGetOrderTotal($orderNo)
        );


        $customer = customFunctionToGetCustomerDetails($orderNo);

        $params['returnUrl'] = '/payment-gateway-process/' . $orderNo .  '/'; //this is the Sagepay NotificationURL

        $params['card'] = array(
            'firstName' => $customer['billing_firstname'],
            'lastName' => $customer['billing_lastname'],
            'email' => $customer['billing_email'],
            'billingAddress1' => $customer['billing_address1'],
            'billingAddress2' => $customer['billing_address2'],
            'billingCity' => $customer['billing_town'],
            'billingPostcode' => $customer['billing_postcode'],
            'billingCountry' => $customer['billing_country'],
            'billingPhone' => $customer['billing_telephone'],
            'shippingAddress1' => $customer['delivery_address1'],
            'shippingAddress2' => $customer['delivery_address2'],
            'shippingCity' => $customer['delivery_town'],
            'shippingPostcode' => $customer['delivery_postcode'],
            'shippingCountry' => $customer['delivery_country']
        );


        try {
            $response = $this->gateway->purchase($params)->send();


            if ($response->isSuccessful()) :

                //not using this part

            elseif ($response->isRedirect()) :

                $reference = $response->getTransactionReference();
                customFunctionToSaveTransactionReference($orderNo, $reference);
                $response->redirect();

            else :
                //do something with an error
                echo $response->getMessage();

            endif;

        } catch (\Exception $e) {

            //do something with this if an error has occurred
            echo 'Sorry, there was an error processing your payment. Please try again later.';
        }



    }


    public function processPayment($orderNo)
    {

        $params = array(
            'description'=> 'Online order',
            'currency'=> 'GBP',
            'transactionId'=> $orderNo,
            'amount'=> customFunctionToGetOrderTotal($orderNo)
        );

        $customer = customFunctionToGetCustomerDetails($orderNo);


        $transactionReference = customFunctionToGetTransactionReference($orderNo);


        try {
            $response = $this->gateway->completePurchase(array(
                'transactionId' => $orderNo,
                'transactionReference' => $transactionReference,
            ))->send();

            customFunctionToSaveStatus($orderNo, array('payment_status' => $response->getStatus()));
            customFunctionToSaveMessage($orderNo, array('gateway_response' => $response->getMessage()));

            //encrypt it to stop anyone being able to view other orders
            $encodeOrderNo = customFunctionToEncodeOrderNo($orderNo);
            $response->confirm('/payment-gateway-response/' . $encodeOrderNo);

        } catch(InvalidResponseException $e) {
            // Send "INVALID" response back to SagePay.
            $request = $this->gateway->completePurchase(array());
            $response = new \Omnipay\SagePay\Message\ServerCompleteAuthorizeResponse($request, array());

            customFunctionToSaveStatus($orderNo, array('payment_status' => $response->getStatus()));
            customFunctionToSaveMessage($orderNo, array('gateway_response' => $response->getMessage()));

            redirect('/payment-error-response/');
        }



    }


    public function paymentResponse($encodedOrderNo)
    {
        $orderNo = customFunctionToDecode($encodedOrderNo);
        $sessionOrderNo = customFunctionToGetOrderNo(); 
        if ($orderNo != $sessionOrderNo) :
            //do something here as someone is trying to fake a successful order
        endif;
        $status = customFunctionToGetOrderStatus($orderNo);

        switch(strtolower($status)) :
            case 'ok' :
                customFunctionToHandleSuccess($orderNo);
            break;

            case 'rejected' :
            case 'notauthed' :
                //do something to handle failed payments
            break;

            case 'error' :
               //do something to handle errors

            break;

            default:

                //do something if it ever reaches here

        endswitch;


    }

 }
于 2015-04-08T12:22:02.677 回答
1

我昨晚做了一个关于这个的演讲,并将工作演示脚本放在 github 上:

https://github.com/academe/OmniPay-SagePay-Demo

SagePay Direct 是一次性操作 - OmniPay 发送交易详细信息并立即获得响应。

SagePay 服务器涉及将用户重定向到 SagePay 网站,以使用他们的卡详细信息授权交易。此 API 使用通知消息,其中 SagePay 将使用授权结果直接调用您的应用程序。这发生在用户会话之外,因此需要将事务存储在数据库中,以便可以在两个事务之间共享。

所有这些都在上面链接的脚本中。authorize.php会做授权。编辑它以使用SagePay\DirectSagePay\Server查看它是如何工作的。SagePay\Serveris和 that的通知处理程序sagepay-confirm.php最终将用户发送到final.php可以从存储在数据库中的事务中读取结果的位置。

这些脚本都被注释了并且应该是有意义的,但是请随时在此处或在该 github 存储库的问题跟踪器中提出更多关于它们的问题。

不过,我还没有尝试过SagePay\Direct使用 3D-Secure。假设组合是一个东西,脚本可能需要一些修改来支持它。

于 2015-06-17T13:15:59.340 回答