How to implement Authorize.NET Hosted Payments iFrame & Laravel

I found the official documentation and the github example provided by Authorize.NET to be a terribly confusing mess that you don't need. This post is a summary of the last few hours of work, hoping this can help others.

This guide assumes that you do not need a receipt page, and you want to automatically move the user forward when payment is successful.

+4
source share
1 answer

The source code for the site is Laravel (PHP), but not much about Laravel here.

The first thing to do is add the Authorize.NET SDK:

composer require authorizenet/authorizenet

, , , , , .

<?php

namespace ShopApp\Repositories;
use ShopApp\Models\Order;
use ShopApp\Repositories\Contracts\hostedPaymentRepositoryContract;
use Illuminate\Support\Facades\Config;
use net\authorize\api\contract\v1\MerchantAuthenticationType;
use net\authorize\api\contract\v1\TransactionRequestType;
use net\authorize\api\controller\GetHostedPaymentPageController;
use net\authorize\api\contract\v1\GetHostedPaymentPageRequest;
use net\authorize\api\contract\v1\SettingType;
use net\authorize\api\constants\ANetEnvironment;
use net\authorize\api\contract\v1\CustomerAddressType;
use ShopApp\Models\Address;

/**
 * Class hostedPaymentRepository
 * @package ShopApp\Repositories
 * @todo - Implement methods to talk to Authorize.NET and show form.
 */

class hostedPaymentRepository implements hostedPaymentRepositoryContract
{

    public $response; //what did we get back?
    public $paymentFormToken;

    public function getHostedFormToken(Order $order){

        $payment_amount = null;

        foreach($order->items as $order_item){

            $payment_amount += $order_item->price;

        }

        $billing_address = Address::findOrFail($order->billing_address_id);

        // Common setup for API credentials
        $merchantAuthentication = new MerchantAuthenticationType();
        $merchantAuthentication->setName(Config::get('yoursite.payment_providers.authorize_dot_net.MERCHANT_LOGIN_ID'));
        $merchantAuthentication->setTransactionKey(Config::get('yoursite.payment_providers.authorize_dot_net.MERCHANT_TRANSACTION_KEY'));

        //create a transaction
        $transactionRequestType = new TransactionRequestType();
        $transactionRequestType->setTransactionType("authCaptureTransaction");
        $transactionRequestType->setAmount($payment_amount);

        // Create the Bill To info
        $billto = new CustomerAddressType();
        $billto->setFirstName($order->billing_first_name);
        $billto->setLastName($order->billing_last_name);
        $billto->setAddress($billing_address->address_1);
        $billto->setCity($billing_address->city);
        $billto->setState($billing_address->state);
        $billto->setZip($billing_address->zip);
        $billto->setCountry($billing_address->country);

        if(!is_null($order->phone)){

            $billto->setPhoneNumber($order->phone);

        }

        //@todo - implement user stuff and get email
        //$billto->setEmail("changethis@later.com");

        $transactionRequestType->setBillTo($billto);

        // Set Hosted Form options
        $setting1 = new SettingType();
        $setting1->setSettingName("hostedPaymentButtonOptions");
        $setting1->setSettingValue("{\"text\": \"Pay Now\"}");

        $setting2 = new SettingType();
        $setting2->setSettingName("hostedPaymentOrderOptions");
        $setting2->setSettingValue("{\"show\": false}");

        $setting3 = new SettingType();
        $setting3->setSettingName("hostedPaymentReturnOptions");
        $setting3->setSettingValue("{\"showReceipt\" : false }");

        $setting4 = new SettingType();
        $setting4->setSettingName("hostedPaymentIFrameCommunicatorUrl");
        $setting4->setSettingValue("{\"url\": \"https://yoursite.local/checkout/payment/response\"}");


        // Build transaction request
        $request = new GetHostedPaymentPageRequest();
        $request->setMerchantAuthentication($merchantAuthentication);
        $request->setTransactionRequest($transactionRequestType);

        $request->addToHostedPaymentSettings($setting1);
        $request->addToHostedPaymentSettings($setting2);
        $request->addToHostedPaymentSettings($setting3);
        $request->addToHostedPaymentSettings($setting4);

        //execute request
        $controller = new GetHostedPaymentPageController($request);
        $response = $controller->executeWithApiResponse(ANetEnvironment::SANDBOX);

        if (($response == null) && ($response->getMessages()->getResultCode() != "Ok") )
        {
            return false;
        }

        return $response->getToken();
    }

}

, showReceipt false, hostPaymentIFrameCommunicatorUrl. , PaymentIFrameCommunicatorUrl reciept , showReceipt false.

HostPaymentIFrameCommunicatorUrl , .

, , iFrame ( , :

<div id="iframe_holder" class="center-block" style="width:90%;max-width: 1000px" data-mediator="payment-form-loader">
    <iframe id="load_payment" class="embed-responsive-item" name="load_payment" width="750" height="900" frameborder="0" scrolling="no">
    </iframe>

    <form id="send_hptoken" action="https://test.authorize.net/payment/payment" method="post" target="load_payment">
        <input type="hidden" name="token" value="{{ $hosted_payment_form_token }}" />
    </form>

</div>

javascript (im, jQuery transactResponse, ):

$(document).ready(function(){

    window.CommunicationHandler = {};

    function parseQueryString(str) {
        var vars = [];
        var arr = str.split('&');
        var pair;
        for (var i = 0; i < arr.length; i++) {
            pair = arr[i].split('=');
            vars[pair[0]] = unescape(pair[1]);
        }
        return vars;
    }

    window.CommunicationHandler.onReceiveCommunication = function (argument) {

        console.log('communication handler enter');

        var params = parseQueryString(argument.qstr)

        switch(params['action']){
            case "resizeWindow"     :

                console.log('resize'); break;

            case "successfulSave"   :

                console.log('save'); break;

            case "cancel"           :

                console.log('cancel'); break;

            case "transactResponse" :

                sessionStorage.removeItem("HPTokenTime");

                console.log('transaction complete');

                var transResponse = JSON.parse(params['response']);

                window.location.href = '/checkout/complete';

        }
    }

    //send the token
    $('#send_hptoken').submit();


});

​​ , iFrame Communicator ( ), .

" iframe". , , .NET,

, HTML- ( , , ).

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>IFrame Communicator</title>
    <script type="text/javascript">

    function callParentFunction(str) {

        if (str && str.length > 0 && window.parent.parent
            && window.parent.parent.CommunicationHandler && window.parent.parent.CommunicationHandler.onReceiveCommunication) {

            var referrer = document.referrer;
            window.parent.parent.CommunicationHandler.onReceiveCommunication({qstr : str , parent : referrer});

        }

    }

    function receiveMessage(event) {

        if (event && event.data) {
            callParentFunction(event.data);
        }

    }

    if (window.addEventListener) {

        window.addEventListener("message", receiveMessage, false);

    } else if (window.attachEvent) {

        window.attachEvent("onmessage", receiveMessage);

    }

    if (window.location.hash && window.location.hash.length > 1) {

        callParentFunction(window.location.hash.substring(1));

    }

</script>
</head>
<body></body>
</html>

window.parent.parent

Authorize.NET hostPaymentIFrameCommunicatorUrl, , iFrame, iFrame . window.parent.parent.

PaymentIFrameCommunicatorUrl script , , , .

, -.

Authorize.NET , . "catch-all", , , .

API- , ...

+7

Source: https://habr.com/ru/post/1676001/


All Articles