{"id":20629937,"url":"https://github.com/academe/omnipay-authorizenetapi","last_synced_at":"2025-04-15T18:18:31.905Z","repository":{"id":42461139,"uuid":"92228339","full_name":"academe/omnipay-authorizenetapi","owner":"academe","description":"Omnipay 3.x implementation of Authorize.Net API","archived":false,"fork":false,"pushed_at":"2022-07-05T14:03:25.000Z","size":113,"stargazers_count":14,"open_issues_count":15,"forks_count":11,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-04-15T09:14:54.758Z","etag":null,"topics":["authorize-net","authorizenet","omnipay","payment-gateway","php"],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/academe.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-05-23T23:07:42.000Z","updated_at":"2024-02-29T10:37:27.000Z","dependencies_parsed_at":"2022-09-24T04:11:26.249Z","dependency_job_id":null,"html_url":"https://github.com/academe/omnipay-authorizenetapi","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/academe%2Fomnipay-authorizenetapi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/academe%2Fomnipay-authorizenetapi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/academe%2Fomnipay-authorizenetapi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/academe%2Fomnipay-authorizenetapi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/academe","download_url":"https://codeload.github.com/academe/omnipay-authorizenetapi/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249125998,"owners_count":21216705,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["authorize-net","authorizenet","omnipay","payment-gateway","php"],"created_at":"2024-11-16T14:06:28.183Z","updated_at":"2025-04-15T18:18:31.884Z","avatar_url":"https://github.com/academe.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n[![Build Status](https://travis-ci.org/academe/omnipay-authorizenetapi.svg?branch=master)](https://travis-ci.org/academe/omnipay-authorizenetapi)\n[![Latest Stable Version](https://poser.pugx.org/academe/omnipay-authorizenetapi/v/stable)](https://packagist.org/packages/academe/omnipay-authorizenetapi)\n[![Total Downloads](https://poser.pugx.org/academe/omnipay-authorizenetapi/downloads)](https://packagist.org/packages/academe/omnipay-authorizenetapi)\n[![Latest Unstable Version](https://poser.pugx.org/academe/omnipay-authorizenetapi/v/unstable)](https://packagist.org/packages/academe/omnipay-authorizenetapi)\n[![License](https://poser.pugx.org/academe/omnipay-authorizenetapi/license)](https://packagist.org/packages/academe/omnipay-authorizenetapi)\n\nTable of Contents\n=================\n\n   * [Table of Contents](#table-of-contents)\n   * [Omnipay-AuthorizeNetApi](#omnipay-authorizenetapi)\n   * [Installation](#installation)\n   * [Authorize.Net API](#authorizenet-api)\n      * [API Authorize/Purchase (Credit Card)](#api-authorizepurchase-credit-card)\n      * [API Capture](#api-capture)\n      * [API Authorize/Purchase (Opaque Data)](#api-authorizepurchase-opaque-data)\n      * [API Void](#api-void)\n      * [API Refund](#api-refund)\n      * [API Fetch Transaction](#api-fetch-transaction)\n   * [Hosted Payment Page](#hosted-payment-page)\n      * [Hosted Payment Page Authorize/Purchase](#hosted-payment-page-authorizepurchase)\n   * [Webhook Notifications](#webhook-notifications)\n\n# Omnipay-AuthorizeNetApi\n\nOmnipay 3.x implementation of Authorize.Net API\n\n# Installation\n\n    composer require \"academe/omnipay-authorizenetapi: ~3.0\"\n\n# Authorize.Net API\n\nThe *Authorize.Net API* driver handles server-to-server requests.\nIt is used both for direct card payment (though check PCI requirements)\nand for creating transactions using a card token generated client-side.\n\n## API Authorize/Purchase (Credit Card)\n\nThe following example is a simple authorize with supplied card details.\n*You would normally avoid allowing card details near your merchant site\nback end for PCI compliance reasons,\nsupplying a tokenised card reference instead (see later section for this).*\n\n```php\n\u003c?php\n\ninclude 'vendor/autoload.php';\n\n$gateway = Omnipay\\Omnipay::create('AuthorizeNetApi_Api');\n\n$gateway-\u003esetAuthName('XXXXXxxxxxx');\n$gateway-\u003esetTransactionKey('XXXXX99999xxxxx');\n$gateway-\u003esetTestMode(true);\n\n$creditCard = new Omnipay\\Common\\CreditCard([\n    // Swiped tracks can be provided instead, if the card is present.\n    'number' =\u003e '4000123412341234',\n    'expiryMonth' =\u003e '12',\n    'expiryYear' =\u003e '2020',\n    'cvv' =\u003e '123',\n    // Billing and shipping details can be added here.\n]);\n\n// Generate a unique merchant site transaction ID.\n$transactionId = rand(100000000, 999999999);\n\n$response = $gateway-\u003eauthorize([\n    'amount' =\u003e '7.99',\n    'currency' =\u003e 'USD',\n    'transactionId' =\u003e $transactionId,\n    'card' =\u003e $creditCard,\n    // Additional optional attributes:\n    'customerId' =\u003e '123456',\n    'customerType' =\u003e \\Academe\\AuthorizeNet\\Request\\Model\\Customer::CUSTOMER_TYPE_INDIVIDUAL,\n    'customerDriversLicense' =\u003e [\n        'number' =\u003e '123456',\n        'state' =\u003e 'NY',\n        'dateOfBirth' =\u003e '1967-01-01',\n    ],\n    'customerTaxId' =\u003e 'TAX456',\n])-\u003esend();\n\n// Or use $gateway-\u003epurchase() to immediately capture.\n\nvar_dump($response-\u003eisSuccessful());\n// bool(true)\n\nvar_dump($response-\u003egetCode());\n// string(1) \"1\"\n\nvar_dump($response-\u003egetMessage());\n// string(35) \"This transaction has been approved.\"\n\nvar_dump($response-\u003egetTransactionReference());\n// string(11) \"60103474871\"\n```\n\n## API Capture\n\nOnce authorized, the amount can be captured:\n\n```php\n// Captured from the authorization response.\n$transactionReference = $response-\u003egetTransactionReference();\n\n$response = $gateway-\u003ecapture([\n    'amount' =\u003e '7.99',\n    'currency' =\u003e 'USD',\n    'transactionReference' =\u003e $transactionReference,\n])-\u003esend();\n```\n\n## API Authorize/Purchase (Opaque Data)\n\nThe \"Opaque Data\" here is a tokenised credit or debit card.\nAuthorize.Net can tokenise cards in a number of ways, one of which\nis through the `accept.js` package on the front end.\nIt works like this:\n\nYou build a payment form in your page.\nAs well as hard-coding it as shown below, the gateway provides a method\nyou can use to generate it dynamically.\n\n```html\n\u003cform id=\"paymentForm\"\n    method=\"POST\"\n    action=\"https://your-site.example.com/authorize\"\u003e\n    \u003cinput type=\"text\" id=\"cardNumber\" placeholder=\"cardNumber\"/\u003e\n    \u003cinput type=\"text\" id=\"expMonth\" placeholder=\"expMonth\"/\u003e\n    \u003cinput type=\"text\" id=\"expYear\" placeholder=\"expYear\"/\u003e\n    \u003cinput type=\"text\" id=\"cardCode\" placeholder=\"cardCode\"/\u003e\n    \u003cinput type=\"hidden\" name=\"opaqueDataValue\" id=\"opaqueDataValue\" /\u003e\n    \u003cinput type=\"hidden\" name=\"opaqueDataDescriptor\" id=\"opaqueDataDescriptor\" /\u003e\n    \u003cbutton\u003ePay Now\u003c/button\u003e\n\u003c/form\u003e\n```\n\nNote the card detail elements do not have names, so will not be submitted\nto your site. This is important for PCI reasons.\nTwo hidden fields are defined to carry the opaque data to your site.\nYou can include as many other fields as you like in the same form,\nwhich may include a name and an address.\n\nAfter the payment form, you will need the `accept.js` JavaScript:\n\n```javascript\n    \u003cscript type=\"text/javascript\"\n        src=\"https://jstest.authorize.net/v1/Accept.js\"\n        charset=\"utf-8\"\u003e\\\n    \u003c/script\u003e\n```\n\nUse the `https://js.authorize.net/v1/Accept.js` URL for production.\n\nYou need to catch the \"Pay Now\" submission and send it to a function to\nprocess the card details. Either an `onclick` attribute or a jQuery event\nwill work. For example:\n\n    \u003cbutton type=\"button\" onclick=\"sendPaymentDataToAnet()\"\u003ePay\u003c/button\u003e\n\nThe `sendPaymentDataToAnet` function handles the tokenisation.\n\n```javascript\n\u003cscript type=\"text/javascript\"\u003e\nfunction sendPaymentDataToAnet() {\n    // Set up authorisation to access the gateway.\n    var authData = {};\n        authData.clientKey = \"YOUR PUBLIC CLIENT KEY\";\n        authData.apiLoginID = \"YOUR API LOGIN ID\";\n\n    // Capture the card details from the payment form.\n    // The cardCode is the CVV.\n    // You can include fullName and zip fields too, for added security.\n    // You can pick up bank account fields in a similar way, if using\n    // that payment method.\n    var cardData = {};\n        cardData.cardNumber = document.getElementById(\"cardNumber\").value;\n        cardData.month = document.getElementById(\"expMonth\").value;\n        cardData.year = document.getElementById(\"expYear\").value;\n        cardData.cardCode = document.getElementById(\"cardCode\").value;\n\n    // Now send the card data to the gateway for tokenisation.\n    // The responseHandler function will handle the response.\n    var secureData = {};\n        secureData.authData = authData;\n        secureData.cardData = cardData;\n        Accept.dispatchData(secureData, responseHandler);\n}\n\u003c/script\u003e\n```\n\nThe response handler is able to provide errors that may have been\ngenerated while trying to tokenise the card.\nBut if all is well, it updates the payment form with the opaque data\n(another function `paymentFormUpdate`):\n\n```javascript\nfunction responseHandler(response) {\n    if (response.messages.resultCode === \"Error\") {\n        var i = 0;\n        while (i \u003c response.messages.message.length) {\n            console.log(\n                response.messages.message[i].code + \": \" +\n                response.messages.message[i].text\n            );\n            i = i + 1;\n        }\n    } else {\n        paymentFormUpdate(response.opaqueData);\n    }\n}\n```\n\nPopulate the opaque data hidden form items, then finally submit the form:\n\n```javascript\nfunction paymentFormUpdate(opaqueData) {\n    document.getElementById(\"opaqueDataDescriptor\").value = opaqueData.dataDescriptor;\n    document.getElementById(\"opaqueDataValue\").value = opaqueData.dataValue;\n    document.getElementById(\"paymentForm\").submit();\n}\n```\n\nBack at the server, you will have two opaque data fields to capture:\n\n* opaqueDataDescriptor\n* opaqueDataValue\n\nInitiate an `authorize()` or `purchase()` at the backend, as described in\nthe previous section. In the `creditCard` object, leave the card details\nblank, not set. Instead, send the opaque data:\n\n```php\n$request = $gateway-\u003eauthorize([\n    ...\n    'opaqueDataDescriptor' =\u003e $opaqueDataDescriptor,\n    'opaqueDataValue' =\u003e $opaqueDataValue,\n]);\n```\n\nor\n\n```php\n$request-\u003esetOpaqueData($opaqueDataDescriptor, $opaqueDataValue);\n```\n\nor join with a colon (:) to handle as a card token:\n\n```php\n$request-\u003esetToken($opaqueDataDescriptor . ':' . $opaqueDataValue);\n```\n\nThe authorize or purchase should then go ahead as though the card\ndetails were provided directly. In the result, the last four digits\nof the card will be made available in case a refund needs to be performed.\n\nFurther details can be \n[found in the official documentation](https://developer.authorize.net/api/reference/features/acceptjs.html).\n\nNote also that the opaque data is used for other payment sources, such as\nbank accounts and PayPal.\n\n## API Void\n\nAn authorized transaction can be voided:\n\n```php\n// Captured from the authorization response.\n$transactionReference = $response-\u003egetTransactionReference();\n\n$response = $gateway-\u003evoid([\n    'transactionReference' =\u003e $transactionReference,\n])-\u003esend();\n```\n\n## API Refund\n\nA cleared credit card payment can be refunded, given the original\ntransaction reference, the original amount, and the last four digits\nof the credit card:\n\n```php\n$response = $gateway-\u003erefund([\n    'amount' =\u003e '7.99',\n    'currency' =\u003e 'USD',\n    'transactionReference' =\u003e $transactionReference,\n    'numberLastFour' =\u003e '1234',\n])-\u003esend();\n```\n\n## API Fetch Transaction\n\nAn existing transaction can be fetched from the gateway given\nits `transactionReference`:\n\n```php\n$response = $gateway-\u003efetchTransaction([\n    'transactionReference' =\u003e $transactionReference,\n])-\u003esend();\n```\n\nThe Hosted Payment Page will host the payment form on the gateway.\nThe form can be presented to the user as a full page redirect or in an iframe.\n\n# Hosted Payment Page\n\nThe Hosted Payment Page is a different gateway:\n\n```php\n$gateway = Omnipay\\Omnipay::create('AuthorizeNetApi_HostedPage');\n```\n\nThe gateway is configured the same way as the direct API gateway,\nand the authorize/purchase\nrequests are created in the same way, except for the addition of\n`return` and `cancel` URLs:\n\n## Hosted Payment Page Authorize/Purchase\n\n```php\n$request = $gateway-\u003eauthorize([\n    'amount' =\u003e $amount,\n    // etc.\n    'returnUrl' =\u003e 'return URL after the transaction is approved or rejected',\n    'cancelUrl' =\u003e 'URL to use if the user cancels the transaction',\n]);\n```\n\nThe response will be a redirect, with the following details used to\nconstruct the redirect in the merchant site:\n\n```php\n$response = $request-\u003esend();\n\n$response-\u003egetRedirectMethod();\n// Usually \"POST\"\n\n$response-\u003egetRedirectUrl();\n// The redirect URL or POST form action.\n\n$response-\u003egetRedirectData()\n// Array of name/value elements used to construct hidden fields\n// in the POST form.\n```\n\nA naive POST \"pay now\" button may look like the following form.\n\n```php\n$method = $response-\u003egetRedirectMethod();\n$action = $response-\u003egetRedirectUrl();\n\necho \"\u003cform method='$method' action='$action'\u003e\";\nforeach ($response-\u003egetRedirectData() as $name =\u003e $value) {\n    $dataName = htmlspecialchars($name);\n    $dataValue = htmlspecialchars($value);\n\n    echo \"\u003cinput type='hidden' name='$dataName' value='$dataValue' /\u003e\";\n}\necho \"\u003cbutton type='submit'\u003ePay Now\u003c/button\u003e\";\necho \"\u003c/form\u003e\";\n```\n\nThis will take the user to the gateway payment page, looking something\nlike this by default:\n\n------\n![Default Gateway Payment Page](docs/authorizenet-default-payment-form.png)\n------\n\nThe billing details will be prefilled with the card details supplied\nin the `$gateway-\u003eauthorize()`.\nWhat the user can change and/or see, can be changed using options or\nconfiration in the account.\n\nTaking the `hostedPaymentPaymentOptions` as an example,\nthis is how the options are set:\n\nThe [documentation](https://developer.authorize.net/api/reference/features/accept_hosted.html)\nlists `hostedPaymentPaymentOptions` as supporting these options:\n`{\"cardCodeRequired\": false, \"showCreditCard\": true, \"showBankAccount\": true}`\n\nTo set any of the options, drop the `hostedPayment` prefix from the options\nname, then append with the specific option you want to set, and use the\nresult as the parameter, keeping the name in *camelCase*.\nSo the above set of options are supported by the following parameters:\n\n* paymentOptionsCardCodeRequired\n* paymentOptionsShowCreditCard\n* paymentOptionsShowBankAccount\n\nYou can set these in the `authorize()` stage:\n\n```php\n$request = $gateway-\u003eauthorize([\n    ...\n    // Hide the bank account form but show the credit card form.\n    'paymentOptionsShowCreditCard' =\u003e true,\n    'paymentOptionsShowBankAccount' =\u003e false,\n    // Change the \"Pay\" buton text.\n    'buttonOptionsText' =\u003e 'Pay now',\n]);\n```\n\nor use the `set*()` form to do the same thing:\n\n    $request-\u003esetPaymentOptionsShowBankAccount(false);\n\n# Webhook Notifications\n\nThe Authorize.Net gateway provides a rich set of webhooks to notify the\nmerchant site (and/or other backend systems) about events related to\ncustomers or payments.\nThe [current documentation can be found here](https://developer.authorize.net/api/reference/features/webhooks.html).\n\nFor some API methods, such as the Hosted Payment Page, the webhooks\nare necessary for operation. For other API methods they provide additional\ninformation.\n\nThe webhooks can be configured in the Authorize.Net account settings page.\nThey can also be fully managed through a REST API, so that a merchant\nsite can register for all the webhooks that it needs.\n*Note that the webhook management RESTful API has not yet been implemented here.*\n\nYour notification handler is set up like this at your webhook endpoint:\n\n```php\n$gateway = Omnipay::create('AuthorizeNetApi_Api');\n\n$gateway-\u003esetAuthName($authName);\n$gateway-\u003esetTransactionKey($authKey);\n$gateway-\u003esetSignatureKey($signatureKey); // HMAC-256\n$gateway-\u003esetTestMode(true); // for false\n\n$notification = $gateway-\u003eacceptNotification();\n```\n\nThis will read and parse the webhook `POST` data.\nThe raw nested array data can be found at:\n\n    $notification-\u003egetData();\n\nThe parsed `Notification` value object can be found at:\n\n    $notification-\u003egetParsedData();\n\nSome details that describe the nature of the notification are:\n\n```php\n// The main target: payment or customer\n$notification-\u003egetEventTarget();\n\n// The event subtarget. e.g. capture, fraud, void, subscription\n$notification-\u003egetEventSubtarget();\n\n// The event action. e.g. created, updated, deleted, held, approved, declined\n$notification-\u003egetEventMethod();\n```\n\nSee here for a full list of the target, subtarget and actions:\nhttps://github.com/academe/authorizenet-objects/blob/master/src/ServerRequest/Notification.php#L24\n\nFor those notifications that contain the `transactionReference`, this can be\nobtained:\n\n    $notification-\u003egetTransactionReference();\n\nFor any notifications that do not involve a transaction, this will be `null`.\nNote that the webhook does not include the merchant `transactionId`,\nso there is nothing to tie the payment webhook back to a Hosted Page request.\nIn this case, you can supply the `transactionId` as a query parameter\non the `notifyUrl` when creating the Hosted Payment Page data.\nHowever, do be aware this ID will be visible to end users monitoring\nbrowser traffic, and the ID (being in the URL) will not be included\nin the notification signing, so could be faked. It is unlikely, but just\nbe aware that it is a potential attack vector, so maybe self-sign the URL\ntoo.\n\nNotifications can be signed by the gateway using a `signatureKey`.\nBy default, this notification handler will verify the `signature`\nand throw an exception if it failes to validate against the key\nyou provide when fetching the result of the transaction.\n\nA manual check of the `signature` can be made using:\n\n    $notification-\u003eisSignatureValid()\n\nThis will return `true` if the signature is valid,  or `false` if any\npart of the verification process fails.\n\nValidation of the `signature` can be disabled if needed:\n\n    $gateway-\u003esetDisableWebhookSignature(true);\n\nFor consistency with other Omipay Drivers, this driver *may* make an\nopinionated decision on how the `transactionId` is passed into the\nnotification handler, but only after researchign how other people are\nhandling it.\nThere is a front-end way to do it through an iframe, but it seems\nvulnerable to user manipulation to me.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Facademe%2Fomnipay-authorizenetapi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Facademe%2Fomnipay-authorizenetapi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Facademe%2Fomnipay-authorizenetapi/lists"}