Sending leads can be used in four cases:

  • Sending new leads to CRM. Classic transfer of leads to a third-party network. Every minute, all leads in the "New" status are sent to the target CRM. Upon successful submission, the lead is transferred to the "Processing" status. In case of problems - in the "Cancel" status with the corresponding reason. In case of sending errors, it remains in the "New" status for sending in a minute.
  • Sending upsells and changes. Sometimes the lead can be modified by a request from the site that is sent from the "Thank you" page. Changes are sent to the target CRM every minute.
  • Senging approved leads to CRM. Sends leads to the target network after being processed by the call center. You can choose the status from which the sending occurs. From "Packaging" it is convenient to send leads to the fulfillment service, from "Send" - to the delivery service, from "Delivery" - to the delivery monitoring call center.
  • Synchronous sending of lead for registration. Sends data to the target CRM when a lead arrives. Required to implement the automatic login mechanism (autologin).

All integrations have a similar approach to links, fields, and processing code. The request is executed separately for each lead. Links and fields work with the same set of macros. The processing code should always end with the return of the result.

Send URL

This is the URL to which the request will be made. You can use these macros in the address:

  • {id} - order ID.
  • {ip} - customer IP address.
  • {wm} - affiliate ID.
  • {wmi} - smart affiliate identifier that sends data as agent-affiliate for agent traffic.
  • {name} - customer name.
  • {phone} - customer phone.
  • {ofp:xxx} - the value of offer parameter with name xxx.
  • {ofpg:xxx} - the value of geo-specific offer parameter with name xxx.
  • {meta:xxx} - the value of order custom field with name xxx.
  • {goal:xxx} - the value of goal parameter with name xxx.
  • {site:xxx} - the value of site parameter with name xxx.

You can also manipulate the address via the $url variable in the preprocessing code.

Preprocessing code

The main methods of using the preprocessing code are described in the corresponding section of the documentation. When sending leads, the following data variables are available to you:

  • $o - raw order data directly from the database.
  • $o['order_country'] - order country ISO code.
  • $o['offer_id'] - offer ID.
  • $ofps - offer parameters.
  • $ofpg - geo-specific offer parameters.
  • $gpar - goal parameters.
  • $spar - site parameters.
  • $vars - nested products list.
  • $meta - order custom fields.

When working with product integrations, you may need to get the order contents. It is stored in the $o['order_items'] field, which can be obtained like this:

$its = xxdec( $o['order_items'] );

Inside $its is an array of products in the order. The array key is the product ID. Array fields:

  • 0: quantity of goods in the order.
  • 1: unit price in order currency.
  • 2: unit net cost of goods in order currency.

An example of preparing an array of goods for sending:

$post['items'] = [];
$its = xxdec( $o['order_items'] );
$itp = $core->cpa->get( 'vpar', $o['offer_id'], 'sku' );
foreach ( $its as $it => $iv ) {
  $post['items'][] = [
    'id' => $itp[$it],
    'price' => $iv[1],
    'amount' => $iv[0],

Data fields

The composition of the order is best formed through the fields. The list of fields is specified in the "name value" format separated by a space, each field is on its own line. The value can be either a string or a macro. You can also specify macros within a string.

Main data macros:

  • {id} - order ID.
  • {eid} - encrypted order ID.
  • {ext} - order ID on the side of the target CRM (for submitting changes).
  • {name} - customer name.
  • {last} - customer sirname from last field.
  • {fname} - customer full name.
  • {email} - customer email.
  • {pass} - customer password from custom field pass.
  • {lang} - customer language from lang field or country data.
  • {langup} - customer language in capital letters.
  • {iname} and {ilast} - smart first and last name obtained from additional fields or by splitting the name in half (use only both at once).
  • {ipass} - smart password derived from the pass field or generated on the fly.
  • {imail} - smart mail, generated with an empty field in the form
  • {phone} - customer phone.
  • {iphone} - customer phone with leading + sign.
  • {cphone} - customer phone without country code.
  • {phonecc} - telephone country code from the phonecc and phc fields.
  • {iphonecc} - telephone country code with leading + sign.
  • {geo} and {country} - ISO country code in small letters.
  • {geoup} - ISO country code in capital letters.
  • {comment} - order comment.
  • {index} - ZIP code for delivery.
  • {area} - delivery region.
  • {city} - delivery city.
  • {street} - delivery street.
  • {house} - house, building and apartment.
  • {addr} - delivery address without zip code.
  • {fulladdr} - delivery address with zip code.
  • {straddr} - delivery address from street and house.
  • {delivery} - internal delivery type identifier.
  • {discount} - product discount percentage.
  • {count} - quantity of goods.
  • {currency} - internal currency identifier in the system.
  • {curr} - three-letter ISO currency code.
  • {price} - total order price.
  • {base} - unit price.
  • {delpr} - shipping cost.
  • {more} - additional markup or discount on delivery in the currency of the order.
  • {offer} - offer ID.
  • {siteurl} - smart landing address that uses the url parameter, the real order site address or the default site address.
  • {sitename} - landing name.
  • {spaceurl} - prelanding URL.
  • {spacename} - prelanding name.
  • {land} - landing URL if available.
  • {preland} - prelanding URL if available.
  • {domain} - site domain if available.
  • {wmi} - smart affiliate identifier that sends data as agent-affiliate for agent traffic.
  • {wmname} - affiliate name.
  • {wmmail} - affiliate email.
  • {exti} - agency ID.
  • {extu} - order ID on the side of the agency.
  • {exts} - source ID on the side of the agency.
  • {click} - internal click ID.
  • {subid} - the value of subid or x32 tag.
  • {uuid} - the value of uuid or x64 tag.
  • {sub1} - the value of sub1 tag.
  • {sub2} - the value of sub2 tag.
  • {sub3} - the value of sub3 tag.
  • {sub4} - the value of sub4 tag.
  • {sub5} - the value of sub5 tag.
  • {utms} - the value of utm_source.
  • {utmc} - the value of utm_campaign tag.
  • {utmn} - the value of utm_content tag.
  • {utmt} - the value of utm_term tag.
  • {utmm} - the value of utm_medium tag.
  • {ip} - customer IP address.
  • {ip4} - customer IPv4 address or blank for IPv6.
  • {ip6} - customer IPv6 address or blank for IPv4.
  • {ua} - cutomer User-Agent.
  • {mobile} - traffic type: 0 - desktop, 1 - mobile.
  • {bad} - traffic quality: 0 - normal, 1 - suspicious.
  • {cwm} - affiliate commission amount in system currency.
  • {cwmr} - affiliate commission amount in real currency.
  • {cwmc} - ISO code of the real currency of the affiliate commission.
  • {cpay} - advertiser commission amount in system currency.
  • {cpayr} - advertiser commission amount in system currency.
  • {cpayc} - ISO code of the real currency of the advertiser commission.

Parametric fields will substitute the value of the corresponding parameter with the name xxx:

  • {ofp:xxx} - offer parameter.
  • {ofpg:xxx} - geo-specific offer parameter.
  • {goal:xxx} - goal parameter.
  • {site:xxx} - landing site parameter.
  • {space:xxx} - prelanding site parameter.
  • {offer:xxx} - one of the main fields of the offer.
  • {meta:xxx} - order custom field.
  • {file:xxx} - attached file from the custom field.

Files can be used in custom order fields. Uploading files is supported only when using the standard multipart/form-data format, transferring files in JSON requests is not supported.

General information about the processing code

The processing code receives the $result variable as input. It contains the raw server response data. Most often, the server response comes in JSON format, so it's better to convert the result to an array like this:

$r = xxdec( $result );

The processing code must return a result on success. If processing returns false or no result, the request is considered to have failed. Such a request will be queued for resubmission.

Processing code for new leads

When submitting new leads, the system expects to see a new lead ID or an adding error code. If the processing code returned a negative integer, it is regarded as the refusal reason ID and the lead is cancelled. Any other value is considered a lead ID.

For example, the API function for adding orders from a supplier gives us { status: "ok", id: 123 } if successful, and { status: "error", error: "double" } in case of an error adding an order, indicating the error code. The code that implements this would look like this:

$r = xxdec( $result );
if ( $r['status'] == 'ok' ) return $r['id'];
if ( $r['error'] == 'double' ) return -7;
if ( $r['error'] == 'geo' ) return -5;
if ( $r['error'] == 'phone' ) return -1;
return false;

Stub for sending new leads

Sometimes new leads do not need to be sent, it is enough to transfer the order to the processing status. This happens when adding leads via API with an external order ID or when sending a lead for registration synchronously.

To enable the stub, leave all the fields in the "Sending new leads" block empty and check the "Enable sending leads to CRM" checkbox. Orders will be transferred to the "Processing" status once a minute. If orders do not have an external ID, the internal order ID will be entered instead.

Processing code for lead changes

Change processing expects only two values from the code - success or failure. Any non-empty value will be considered a success. Implementation example:

$r = xxdec( $result );
return ( $r['status'] == 'ok' ) ? true : false;

Processing code for approved orders

When processing approved orders, the system expects an order ID from the code on the CRM side. Any non-empty value is treated as an identifier. Implementation example:

$r = xxdec( $result );
if ( $r['status'] == 'ok' ) {
  return $r['id'];
} else return false;

Processing code for synchronous send

When sending synchronously, the system expects from the code a link to enter the personal account for the customer. But it gets it extremely rarely, so it got ready to put up with some options.

  • A full URL will be considered as a successful lead submission. The user will be redirected to the specified address in the personal account. The order remains in the "New" status and awaits the next classic sending.
  • The line of text will be treated as an error message and will be shown to the user on the site. The sending itself will be considered unsuccessful - such a lead is automatically transferred to the "Deleted" status.
  • A negative number will be treated as a rejection reason code, just like when submitting new leads. The lead will be canceled with the specified reason. The user will then see a Thank You page..
  • A positive integer will be treated as a lead ID. Sending is considered successful, the lead is transferred to the "Processing" status with the specified ID. The user sees the "Thank you" page.
  • A string of the form id:xxx (characters id, a colon and an arbitrary value) will also be regarded as a lead ID, similar to the previous paragraph.
  • An empty response is treated as a send error. The lead remains in the "New" status and is sent to the classic sending.

Classic synchronous send processing looks like this:

$r = xxdec( $result );
if ( $r['autologin_url'] ) return $r['autologin_url'];
if ( $r['error_message'] ) return $r['error_message'];
return 'Registration failed, try again later';

Classic processing is never applied. The actual processing code is much more complex and allows for many variations. In the handler, it is recommended to immediately set the external ID of the lead, if it was received:

$core->lead->edit( $o['order_id'], [ 'exto' => $result['id'] ] );

An example of a complete processing code:

$result = json_decode( $result, true );
if ( $result['status'] == 'ok' ) {
  $core->lead->edit( $o['order_id'], [ 'exto' => $result['id'] ] );
  return $result['url'] ? $result['url'] : false;
if ( $result['message'] ) return $result['message'];
if ( $result['error'] == 'duplicate' ) return -7;
if ( $result['error'] == 'ban' ) return -12;
if ( $result['error'] == 'traffic' ) return -15;
return 'Registration failed, try again later';

Using only synchronous send is insecure in terms of traffic loss. If the target CRM failed to respond, the lead will not be transferred to it. Therefore, it is recommended to combine synchronous and classical sends. In this case, in order for the lead not to be sent twice, it is necessary to perform a number of actions.

If the synchronous submission is successful, be sure to specify the lead's external ID as described above. If the target CRM does not use its identifiers, use the internal one:

$core->lead->edit( $o['order_id'], [ 'exto' => $o['order_id'] ] );

At the end of the preprocessing code for sending new leads, add the following lines:

if ( $o['ext_oid'] ) {
  $url = $post = false;
  $result = true;

Add the line to the beginning of the processing code:

if ( $o['ext_oid'] ) return $o['ext_oid'];

These manipulations will disable the real re-request to the target CRM and simply mark the lead with the status "In processing".