Showing results for 
Search instead for 
Did you mean: 

Using the Accept.js Payment Nonce to Charge a Credit Card via Curl



I'm updating an old piece of code that used to post form values directly to the API using curl. It still works perfectly in the original form!


I would like to update this old form to use accept.js, and so far I've gotten to the point where I am getting a valid dataValue back from accept.js, and next I need to post the Payment Nonce back to AuthNet to charge the card.


The documentation says... "On your server you can call the Authorize.Net API just like you would if using actual credit card information. Simply replace the credit card element with the opaque data element." Uhm. What?


I don't know what a "credit card element" or "opaque data element" means to my simple curl request. It looks like this:


  $request = curl_init($post_url); 
    curl_setopt($request, CURLOPT_HEADER, 0); 
    curl_setopt($request, CURLOPT_RETURNTRANSFER, 1); 
    curl_setopt($request, CURLOPT_POSTFIELDS, $post_string); 
    curl_setopt($request, CURLOPT_SSL_VERIFYPEER, FALSE); 
    $post_response = curl_exec($request);
  @curl_close ($ch); // close curl object


I need to change my $post_string so that instead of including the credit card number and expiratioin date, it includes the payment nonce. But it would be super helpful if your API documentation would actually document what that looks like. What are the keys I should be using?


Hello @jenlampton


Can you post your code for creating the request to post?


If you're using the Authorize.Net API, the change can be as simple as changing from this section in Charge a Credit Card:



to Create an Accept Payment Transaction:





Administrator Administrator

Hi @



Can you post your code for creating the request to post?


I had included it in my original post. There is a bit missing, but it was just some looping that generated a string from an array of post values:


  foreach ($submission as $key => $value) {
    if (strcmp(substr($key, 0, 2), "x_") == 0 && $value != '') {
      $post_vars[$key] = $value;

  $post_string = '';
  foreach ($post_vars as $key => $value) {
    $post_string .= "$key=" . urlencode($value) . '&';
  $post_string = rtrim($post_string, '&');

Hi @jenlampton,


Usually, when Richard (or anyone here) says "the Authorize.Net API" we basically just mean "our current API", which has the catchy name of "the Authorize.Net API". We used to have this alphabet soup of a bunch of different APIs for payments and other services (named AIM, CIM, ARB, SIM, DPM, etc), that we've supplanted several years ago with one consolidated API that's usable in JSON or XML flavors.


There's not enough code posted for us to tell if you're using the current API or one of these previous ones, since we don't see the endpoint URL or the field names that are being sent.


Assuming you are using the current API, you'd keep using the code that gets the information from your form fields, but instead of getting the card number or other payment fields, you'd insert the payment nonce that you've received into your $post_string. If you aren't using our current API, there would be a little more rearchitecting involved to structure your request to use the current API. Accept.js is only supported with the current API.


If you could at least post the URL that you're sending the transaction requests too, we'd know at a glance whether that was the current API or an older one.

Usually, when Richard (or anyone here) says "the Authorize.Net API" we basically just mean "our current API", which has the catchy name of "the Authorize.Net API".


Ah, okay. That's a little confusing. Though I suppose I wouldn't know which of the old APIs are in use anyway, since I inherited this code. Actual API names might not even be helpful to me! But no, I don't think I'm using "the current API" because the code @RichardH pasted is completely unlike anything else used.


The post url currently in use is `` for live transactions `` for sandbox ones. I did try to check what the heck that URL mapped to, but I was unable to find a handy chart.


All the values in $post_vars start with 'x_' like so:

$post_vars['x_version']         = "3.1";
$post_vars['x_delim_data']      = "TRUE";
$post_vars['x_delim_char']      = "|";
$post_vars['x_relay_response']  = "FALSE";
$post_vars['x_method']          = "CC";

> you'd insert the payment nonce that you've received into your $post_string.


I understand that much. I was unable to find the query string *keys* needed to add  the nonce (and associaed information) into the $post_string (which is a query string of key/value pairs). Perhaps that is because they can't be sent this way?


Thanks for the support. I appreicate the repsonce,


Hi Jen,


I'm deeply sorry to break this to you, but you are in fact using one of these old APIs. The Accept.js payment nonce can only be sent in a request to the current API.


To modify your code to the current API might not be as difficult as you think. You can check our API Reference for definitions and examples of the current API and its usage.


In your case, your current setup has an HTML form where the form field names match the field names that the request to our system is expecting. It's not quite as simple as just changing the field names in the HTML form, because requests to the current API are structured.


What may work best for you is to put some code into your script that takes the form fields that were posted, and then insert their values into sort of a "template" of a request in XML or JSON form. Here's a chunk of sample code that might get you started.



// make your "template"
$xmlStr = <<<XML <?xml version="1.0" encoding="utf-8"?> <createTransactionRequest xmlns="AnetApi/xml/v1/schema/AnetApiSchema.xsd"> <merchantAuthentication> <name></name> <transactionKey></transactionKey> </merchantAuthentication> <refId></refId> <transactionRequest> <transactionType>authCaptureTransaction</transactionType> <amount></amount> <payment> <opaqueData> <dataDescriptor>COMMON.ACCEPT.INAPP.PAYMENT</dataDescriptor> <dataValue></dataValue> </opaqueData> </payment> </transactionRequest> </createTransactionRequest> XML;
$post_string = new SimpleXMLElement($xmlStr); // the following assumes you've put your credentials in somewhere
// as environment variables called "API_LOGIN_ID" and "TRANSACTION_KEY"
$loginId = getenv("API_LOGIN_ID"); $transactionKey = getenv("TRANSACTION_KEY"); $post_string->merchantAuthentication->addChild('name',$loginId); $post_string->merchantAuthentication->addChild('transactionKey',$transactionKey);

// then insert some more code here to take your posted form fields and
// payment nonce and put them in the right part of the request in the
// same format.
// for example:
// $post_string->opaqueData->addChild('dataValue',$WhateverVariableHasThePaymentNonceInIt);

You'll need to change the URL endpoint to our new API's URL ( for sandbox). You'll also have to set the right Content-Type: header to use in the post request:



curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/xml'));


Then, you'd just use curl to post the $post_string like before.


Let me know if you need any additional help.


Thanks @Aaron,


I've ended up switching to use JSON with Accept.js to avoid these issues, and so far it's mostly working.


I'd like to open a new issue about problems with recurring transactions, but so far I've been unable to even locate how to create a new topic. It's clear that it was possible in 2017, but now...  maybe not?

Hello @jenlampton 


The New Message option is available at the top of page 1, or you can use this link:





Thanks @Richard !

I still hadn't found it before I read your message :) Much appreciated.