Phriction DatingVIP Public Payment Application Project Partner Notifications History Version 11 vs 20
Version 11 vs 20
Version 11 vs 20
Edits
Edits
- Edit by pmiroslawski, Version 20
- Wed, Jan 8 08:32
- Edit by banovic, Version 11
- Mar 20 2017 13:43
Edit Older Version 11... | Edit Current Version 20... |
Content Changes
Content Changes
= Content
[[ public/payment/partners/notifications/#transaction-success | transaction.success ]]
[[ public/payment/partners/notifications/#transaction-failed | transaction.failed ]]
[[ public/payment/partners/notifications/#subscription-created | subscription.created ]]
[[ public/payment/partners/notifications/#subscription-trial | subscription.trial ]]
[[ public/payment/partners/notifications/#subscription-stopped | subscription.stopped ]]
[[ public/payment/partners/notifications/#subscription-suspended | subscription.suspended ]]
[[ public/payment/partners/notifications/#subscription-rebill | subscription.rebill ]]
[[ public/payment/partners/notifications/#subscription-completed | subscription.completed ]]
[[ public/payment/partners/notifications/#subscription-change | subscription.change ]]
[[ public/payment/partners/notifications/#subscriptions-prerebill | subscriptions.prerebill ]]
------
PV2 is sending notifications to our partners regarding various actions on PV2. Notifications are always sent to the same URL defined for each partner along with hash and other related data. If partner doesn't respond to notification, PV2 will try to resend it.
Generally notifications will be sent in this format:
<table>
<tr>
<th>Param Name</th><th>Type</th><th>Description</th>
</tr>
<tr>
<td>command</td><td>string</td><td>The command that needs to be executed</td>
</tr>
<tr>
<td>hash</td><td>string</td><td>Hash</td>
</tr>
<tr>
<td>data</td><td>string</td><td>json encoded string with data array</td>
</tr>
</table>
After receiving notification partner should respond with [[public/payment/partners/apidocs/notifications.hash.validate|notifications.hash.validate]] api call by sending received hash back, otherwise notification will be resent with this schedulle:
# After 1 minute
# After 5 minutes
# After 15 minutes
# After 30 minutes
# After 30 minutes
notifications.hash.validate call also has another important purpose, so partners can validate if the notification actually came from us.
This is list of notifications which will be send out.
= transaction.success
Sent in case of successful transaction.
Data array (json encoded)
<table>
<tr>
<th>Param Name</th><th>Type</th><th>Description</th>
</tr>
<tr><td>tran_id</td><td>int</td><td>**Transaction** ID</td></tr>
<tr><td>ptnr_id</td><td>int</td><td>**Partner** ID</td></tr>
<tr><td>ppac_id</td><td>int</td><td>**Payment Processor Account** ID</td></tr>
<tr><td>order_id</td><td>int</td><td>**Order** ID</td></tr>
<tr><td>ccdt_id</td><td>int</td><td>Credit Card Details ID</td></tr>
<tr><td>transaction_type</td><td>string</td><td>Transaction Type. Values: `s` (sale), `a` (auth), `r` (refund), `c` (chargeback), `f` (fake)</td></tr>
<tr><td>amount</td><td>string</td><td>Amount</td></tr>
<tr><td>currency</td><td>string</td><td>Currency (3 Letter ISO Code)</td></tr>
<tr><td>description</td><td>string</td><td>Description</td></tr>
<tr><td>status</td><td>string</td><td>Transaction status. Values: `failed`, `successful`</td></tr>
<tr><td>refunded_tran_id</td><td>int</td><td>Refunded **Transaction** ID</td></tr>
<tr><td>origin</td><td>string</td><td>Origin. Values: `direct`, `system`</td></tr>
<tr><td>ts</td><td>int</td><td>Timestamp</td></tr>
<tr><td>status_code</td><td>int</td><td>Status code</td></tr>
<tr><td>payment_code</td><td>int</td><td>[[ public/payment/partners/codes/ | Payment Code ]] (700 on success)</td></tr>
<tr><td>order_type</td><td>string</td><td>Order type. Values: `basic`, `xsale`</td></tr>
<tr><td>pp_id</td><td>int</td><td>**Payment Processor** ID</td></tr>
<tr><td>processor</td><td>string</td><td>**Payment Processor** abbreviation</td></tr>
<tr><td>user_id</td><td>int</td><td>User ID in **Payment Application**</td></tr>
<tr><td>tracking_user</td><td>int</td><td>User Identifier from **Partner**</td></tr>
<tr><td>tracking_tag</td><td>int</td><td>Tag ID from **Partner**</td></tr>
<tr><td>items</td><td>array</td><td>Array of items</td></tr>
</table>
= transaction.failed
Sent in case of failed transaction.
Data array (json encoded)
<table>
<tr>
<th>Param Name</th><th>Type</th><th>Description</th>
</tr>
<tr><td>tran_id</td><td>int</td><td>**Transaction** ID</td></tr>
<tr><td>ptnr_id</td><td>int</td><td>**Partner** ID</td></tr>
<tr><td>ppac_id</td><td>int</td><td>**Payment Processor Account** ID</td></tr>
<tr><td>order_id</td><td>int</td><td>**Order** ID</td></tr>
<tr><td>ccdt_id</td><td>int</td><td>Credit Card Details ID</td></tr>
<tr><td>transaction_type</td><td>string</td><td>Transaction Type. Values: `s` (sale), `a` (auth), `r` (refund), `c` (chargeback), `f` (fake)</td></tr>
<tr><td>amount</td><td>string</td><td>Amount</td></tr>
<tr><td>currency</td><td>string</td><td>Currency (3 Letter ISO Code)</td></tr>
<tr><td>description</td><td>string</td><td>Description</td></tr>
<tr><td>status</td><td>string</td><td>Transaction status. Values: `failed`, `successful`</td></tr>
<tr><td>refunded_tran_id</td><td>int</td><td>Refunded **Transaction** ID</td></tr>
<tr><td>origin</td><td>string</td><td>Origin. Values: `direct`, `system`</td></tr>
<tr><td>ts</td><td>int</td><td>Timestamp</td></tr>
<tr><td>status_code</td><td>int</td><td>Status code</td></tr>
<tr><td>payment_code</td><td>int</td><td>[[ public/payment/partners/codes/ | Payment Code ]] (700 on success)</td></tr>
<tr><td>order_type</td><td>string</td><td>Order type. Values: `basic`, `xsale`</td></tr>
<tr><td>pp_id</td><td>int</td><td>**Payment Processor** ID</td></tr>
<tr><td>processor</td><td>string</td><td>**Payment Processor** abbreviation</td></tr>
<tr><td>user_id</td><td>int</td><td>User ID in **Payment Application**</td></tr>
<tr><td>tracking_user</td><td>int</td><td>User Identifier from **Partner**</td></tr>
<tr><td>tracking_tag</td><td>int</td><td>Tag ID from **Partner**</td></tr>
<tr><td>items</td><td>array</td><td>Array of items</td></tr>
</table>
= subscription.created
Sent in case of successfully created subscription
Data array (json encoded)
<table>
<tr>
<th>Param Name</th><th>Type</th><th>Description</th>
</tr>
<tr><td>sub_id</td><td>int</td><td>Subscription ID</td></tr>
<tr><td>item_id</td><td>int</td><td>Item ID</td></tr>
<tr><td>status</td><td>string</td><td>Subscription status (s/b initial on create, rebill after 1st rebill)</td></tr>
<tr><td>start_ts</td><td>int</td><td>Start timestamp</td></tr>
<tr><td>user_id</td><td>int</td><td>PV2 user ID</td></tr>
<tr><td>tracking_user</td><td>int</td><td>User ID on partners' site</td></tr>
<tr><td>ptnr_id</td><td>int</td><td>Partner ID</td></tr>
<tr><td>tracking_tag</td><td>int</td><td>Tracking Tag param</td></tr>
<tr><td>currency</td><td>string</td><td>Currency</td></tr>
<tr><td>hash</td><td>string</td><td>Hash</td></tr>
<tr><td>pp_name</td><td>string</td><td>PP Name</td></tr>
<tr><td>trial_unit</td><td>string</td><td>Trial Unit (day|week|month|year)</td></tr>
<tr><td>trial_period</td><td>int</td><td>Trial period</td></tr>
<tr><td>rebill_unit</td><td>string</td><td>Rebill Unit (day|week|month|year)</td></tr>
<tr><td>rebill_period</td><td>int</td><td>Rebill period</td></tr>
<tr><td>max_rebill_count</td><td>int</td><td>Max Rebill Count</td></tr>
<tr><td>tracking_item</td><td>int</td><td>Tracking item ID</td></tr>
<tr><td>next_rebill_ts</td><td>int</td><td>Next rebill ts</td></tr>
<tr><td>last_rebill_ts</td><td>int</td><td>Last rebill ts</td></tr>
</table>
= subscription.trial
Sent in case of successfully created subscription
Data array (json encoded)
<table>
<tr>
<th>Param Name</th><th>Type</th><th>Description</th>
</tr>
<tr><td>sub_id</td><td>int</td><td>Subscription ID</td></tr>
<tr><td>item_id</td><td>int</td><td>Item ID</td></tr>
<tr><td>status</td><td>string</td><td>Subscription status (s/b initial on create, rebill after 1st rebill)</td></tr>
<tr><td>start_ts</td><td>int</td><td>Start timestamp</td></tr>
<tr><td>user_id</td><td>int</td><td>PV2 user ID</td></tr>
<tr><td>tracking_user</td><td>int</td><td>User ID on partners' site</td></tr>
<tr><td>ptnr_id</td><td>int</td><td>Partner ID</td></tr>
<tr><td>tracking_tag</td><td>int</td><td>Tracking Tag param</td></tr>
<tr><td>currency</td><td>string</td><td>Currency</td></tr>
<tr><td>hash</td><td>string</td><td>Hash</td></tr>
<tr><td>pp_name</td><td>string</td><td>PP Name</td></tr>
<tr><td>trial_unit</td><td>string</td><td>Trial Unit (day|week|month|year)</td></tr>
<tr><td>trial_period</td><td>int</td><td>Trial period</td></tr>
<tr><td>rebill_unit</td><td>string</td><td>Rebill Unit (day|week|month|year)</td></tr>
<tr><td>rebill_period</td><td>int</td><td>Rebill period</td></tr>
<tr><td>max_rebill_count</td><td>int</td><td>Max Rebill Count</td></tr>
<tr><td>tracking_item</td><td>int</td><td>Tracking item ID</td></tr>
<tr><td>next_rebill_ts</td><td>int</td><td>Next rebill ts</td></tr>
<tr><td>last_rebill_ts</td><td>int</td><td>Last rebill ts</td></tr>
</table>
= subscription.stopped
Sent in case of stopped subscription (action initiated via api call)
Data array (json encoded)
<table>
<tr>
<th>Param Name</th><th>Type</th><th>Description</th>
</tr>
<tr><td>sub_id</td><td>int</td><td>Subscription ID</td></tr>
<tr><td>item_id</td><td>int</td><td>Item ID</td></tr>
<tr><td>status</td><td>string</td><td>Subscription status (s/b initial on create, rebill after 1st rebill)</td></tr>
<tr><td>start_ts</td><td>int</td><td>Start timestamp</td></tr>
<tr><td>user_id</td><td>int</td><td>PV2 user ID</td></tr>
<tr><td>tracking_user</td><td>int</td><td>User ID on partners' site</td></tr>
<tr><td>ptnr_id</td><td>int</td><td>Partner ID</td></tr>
<tr><td>tracking_tag</td><td>int</td><td>Tracking Tag param</td></tr>
<tr><td>currency</td><td>string</td><td>Currency</td></tr>
<tr><td>hash</td><td>string</td><td>Hash</td></tr>
<tr><td>pp_name</td><td>string</td><td>PP Name</td></tr>
<tr><td>trial_unit</td><td>string</td><td>Trial Unit (day|week|month|year)</td></tr>
<tr><td>trial_period</td><td>int</td><td>Trial period</td></tr>
<tr><td>rebill_unit</td><td>string</td><td>Rebill Unit (day|week|month|year)</td></tr>
<tr><td>rebill_period</td><td>int</td><td>Rebill period</td></tr>
<tr><td>max_rebill_count</td><td>int</td><td>Max Rebill Count</td></tr>
<tr><td>tracking_item</td><td>int</td><td>Tracking item ID</td></tr>
<tr><td>next_rebill_ts</td><td>int</td><td>Next rebill ts</td></tr>
<tr><td>last_rebill_ts</td><td>int</td><td>Last rebill ts</td></tr>
<tr><td>is_cancel</td><td>boolean</td><td>s/b true</td></tr>
<tr><td>cancel_reason</td><td>string</td><td>Optional, not always sent. If it has value 'cancel_reason_rebill_bin_filter' it means that subscription was stopped because BIN used for purchase is not allowed to rebill.</td></tr>
</table>
= subscription.suspended
Sent in case of suspended subscription (usually happens when we can't rebill user after defined number of attempts)
Data array (json encoded)
<table>
<tr>
<th>Param Name</th><th>Type</th><th>Description</th>
</tr>
<tr><td>sub_id</td><td>int</td><td>Subscription ID</td></tr>
<tr><td>item_id</td><td>int</td><td>Item ID</td></tr>
<tr><td>status</td><td>string</td><td>Subscription status (s/b initial on create, rebill after 1st rebill)</td></tr>
<tr><td>start_ts</td><td>int</td><td>Start timestamp</td></tr>
<tr><td>user_id</td><td>int</td><td>PV2 user ID</td></tr>
<tr><td>tracking_user</td><td>int</td><td>User ID on partners' site</td></tr>
<tr><td>ptnr_id</td><td>int</td><td>Partner ID</td></tr>
<tr><td>tracking_tag</td><td>int</td><td>Tracking Tag param</td></tr>
<tr><td>currency</td><td>string</td><td>Currency</td></tr>
<tr><td>hash</td><td>string</td><td>Hash</td></tr>
<tr><td>pp_name</td><td>string</td><td>PP Name</td></tr>
<tr><td>trial_unit</td><td>string</td><td>Trial Unit (day|week|month|year)</td></tr>
<tr><td>trial_period</td><td>int</td><td>Trial period</td></tr>
<tr><td>rebill_unit</td><td>string</td><td>Rebill Unit (day|week|month|year)</td></tr>
<tr><td>rebill_period</td><td>int</td><td>Rebill period</td></tr>
<tr><td>max_rebill_count</td><td>int</td><td>Max Rebill Count</td></tr>
<tr><td>tracking_item</td><td>int</td><td>Tracking item ID</td></tr>
<tr><td>next_rebill_ts</td><td>int</td><td>Next rebill ts</td></tr>
<tr><td>last_rebill_ts</td><td>int</td><td>Last rebill ts</td></tr>
</table>
= subscription.rebill
Sent after successfully made rebill. It will be sent right after transaction.success
Data array (json encoded)
<table>
<tr>
<th>Param Name</th><th>Type</th><th>Description</th>
</tr>
<tr><td>sub_id</td><td>int</td><td>Subscription ID</td></tr>
<tr><td>item_id</td><td>int</td><td>Item ID</td></tr>
<tr><td>status</td><td>string</td><td>Subscription status (s/b initial on create, rebill after 1st rebill)</td></tr>
<tr><td>start_ts</td><td>int</td><td>Start timestamp</td></tr>
<tr><td>user_id</td><td>int</td><td>PV2 user ID</td></tr>
<tr><td>tracking_user</td><td>int</td><td>User ID on partners' site</td></tr>
<tr><td>ptnr_id</td><td>int</td><td>Partner ID</td></tr>
<tr><td>tracking_tag</td><td>int</td><td>Tracking Tag param</td></tr>
<tr><td>currency</td><td>string</td><td>Currency</td></tr>
<tr><td>hash</td><td>string</td><td>Hash</td></tr>
<tr><td>pp_name</td><td>string</td><td>PP Name</td></tr>
<tr><td>trial_unit</td><td>string</td><td>Trial Unit (day|week|month|year)</td></tr>
<tr><td>trial_period</td><td>int</td><td>Trial period</td></tr>
<tr><td>rebill_unit</td><td>string</td><td>Rebill Unit (day|week|month|year)</td></tr>
<tr><td>rebill_period</td><td>int</td><td>Rebill period</td></tr>
<tr><td>max_rebill_count</td><td>int</td><td>Max Rebill Count</td></tr>
<tr><td>tracking_item</td><td>int</td><td>Tracking item ID</td></tr>
<tr><td>next_rebill_ts</td><td>int</td><td>Next rebill ts</td></tr>
<tr><td>last_rebill_ts</td><td>int</td><td>Last rebill ts</td></tr>
</table>
= subscription.completed
Sent after completed subscription (happens only on subs with limited number of rebills).
Data array (json encoded)
<table>
<tr>
<th>Param Name</th><th>Type</th><th>Description</th>
</tr>
<tr><td>sub_id</td><td>int</td><td>Subscription ID</td></tr>
<tr><td>item_id</td><td>int</td><td>Item ID</td></tr>
<tr><td>status</td><td>string</td><td>Subscription status (s/b initial on create, rebill after 1st rebill)</td></tr>
<tr><td>start_ts</td><td>int</td><td>Start timestamp</td></tr>
<tr><td>user_id</td><td>int</td><td>PV2 user ID</td></tr>
<tr><td>tracking_user</td><td>int</td><td>User ID on partners' site</td></tr>
<tr><td>ptnr_id</td><td>int</td><td>Partner ID</td></tr>
<tr><td>tracking_tag</td><td>int</td><td>Tracking Tag param</td></tr>
<tr><td>currency</td><td>string</td><td>Currency</td></tr>
<tr><td>hash</td><td>string</td><td>Hash</td></tr>
<tr><td>pp_name</td><td>string</td><td>PP Name</td></tr>
<tr><td>trial_unit</td><td>string</td><td>Trial Unit (day|week|month|year)</td></tr>
<tr><td>trial_period</td><td>int</td><td>Trial period</td></tr>
<tr><td>rebill_unit</td><td>string</td><td>Rebill Unit (day|week|month|year)</td></tr>
<tr><td>rebill_period</td><td>int</td><td>Rebill period</td></tr>
<tr><td>max_rebill_count</td><td>int</td><td>Max Rebill Count</td></tr>
<tr><td>tracking_item</td><td>int</td><td>Tracking item ID</td></tr>
<tr><td>next_rebill_ts</td><td>int</td><td>Next rebill ts</td></tr>
<tr><td>last_rebill_ts</td><td>int</td><td>Last rebill ts</td></tr>
</table>
= subscription.change
Sent in when subscription is changed (action initiated via `subscription.change` api call)
Data array (json encoded)
<table>
<tr>
<th>Param Name</th><th>Type</th><th>Description</th>
</tr>
<tr><td>sub_id</td><td>int</td><td>Subscription ID</td></tr>
<tr><td>item_id</td><td>int</td><td>Item ID</td></tr>
<tr><td>status</td><td>string</td><td>Subscription status (s/b initial on create, rebill after 1st rebill)</td></tr>
<tr><td>start_ts</td><td>int</td><td>Start timestamp</td></tr>
<tr><td>user_id</td><td>int</td><td>PV2 user ID</td></tr>
<tr><td>tracking_user</td><td>int</td><td>User ID on partners' site</td></tr>
<tr><td>ptnr_id</td><td>int</td><td>Partner ID</td></tr>
<tr><td>tracking_tag</td><td>int</td><td>Tracking Tag param</td></tr>
<tr><td>currency</td><td>string</td><td>Currency</td></tr>
<tr><td>hash</td><td>string</td><td>Hash</td></tr>
<tr><td>pp_name</td><td>string</td><td>PP Name</td></tr>
<tr><td>trial_unit</td><td>string</td><td>Trial Unit (day|week|month|year)</td></tr>
<tr><td>trial_period</td><td>int</td><td>Trial period</td></tr>
<tr><td>rebill_unit</td><td>string</td><td>Rebill Unit (day|week|month|year)</td></tr>
<tr><td>rebill_period</td><td>int</td><td>Rebill period</td></tr>
<tr><td>max_rebill_count</td><td>int</td><td>Max Rebill Count</td></tr>
<tr><td>tracking_item</td><td>int</td><td>Tracking item ID</td></tr>
<tr><td>next_rebill_ts</td><td>int</td><td>Next rebill ts</td></tr>
<tr><td>last_rebill_ts</td><td>int</td><td>Last rebill ts</td></tr>
</table>
= subscriptions.prerebill
(WIP) Sent from cron job that runs at 1h frequency.
Data consists of subscriptions that are due to rebill in next X days, where X is configurable from cron manager.
(one value of X per one cron job instance)
Data array (json encoded)
<table>
<tr>
<th>Param Name</th><th>Type</th><th>Description</th>
</tr>
<tr><td>interval</td><td>string</td><td>When from now should rebill happen ('2 day', '3 day', 'X day')</td></tr>
<tr><td>subscriptions</td><td>array</td><td>Array of data related to subscriptions rebills (see below)</td></tr>
</table>
Subscriptions array (json encoded)
<table>
<tr>
<th>Param Name</th><th>Type</th><th>Description</th>
</tr>
<tr><td>sub_id</td><td>int</td><td>Subscription ID</td></tr>
<tr><td>next_rebill_ts</td><td>int</td><td>Next rebill timestamp</td></tr>
<tr><td>ptnr_id</td><td>int</td><td>Partner ID</td></tr>
<tr><td>tracking_user</td><td>int</td><td>User ID on partners' site</td></tr>
<tr><td>tracking_tag</td><td>int</td><td>Tracking Tag param</td></tr>
<tr><td>bin</td><td>string</td><td>BIN of card for this susbcription</td></tr>
<tr><td>ccnum_last4</td><td>string</td><td>Last 4 digits of card for this susbcription</td></tr>
<tr><td>currency</td><td>string</td><td>Currency</td></tr>
<tr><td>order_type</td><td>string</td><td>Order type ('basic' | 'xsale')</td></tr>
<tr><td>item_id</td><td>int</td><td>Item ID</td></tr>
<tr><td>cc_type</td><td>string</td><td>Card type ('visa' ...)</td></tr>
<tr><td>pp_name</td><td>string</td><td>PP Name</td></tr>
<tr><td>bin_high_risk</td><td>int</td><td>Is BIN on High Risk List (1|0)</td></tr>
<tr><td>bin_blocked_for_rebill</td><td>int</td><td>Is BIN blocked for rebill (1|0)</td></tr>
</table>
= Partner Notifications
=== Handling notification on partner side
Handling retrieved notifications involves the following steps:
1. Verify if the notification has been sent by PV2.
2. Check if the notification has already been handled.
3. Confirm the handling of the given notification.
==== Ways to Handle Notifications
===== 1. Handling Notifications Using the PV2 Endpoint (Not Recommended)
To meet all requirements, you can call the `notification.hash.validation` endpoint. This endpoint requires the hash of the given notification as an argument. It will return success only if:
- The given hash exists on the PV2 side, and
- The notification has a status of “not handled.”
- At the same time, the endpoint will mark the notification as “handled.”
**Why is this approach not recommended?**
The processes of verification (Step 1) and handling confirmation (Step 2) cannot be separated. If you simply want to verify the notification, it will still be marked as “handled.” This can cause issues because, in the event of an exception during processing, the PV2 system will never reattempt the notification (since handled = 1).
===== 2. Handling Notifications Using the PV2 Endpoint with the verify-only Flag
**Verify the Notification & Check if the Notification Has Been Handled**
In this case, you use the `notification.hash.validation` endpoint with an additional verify-only flag. To do this, append `verify-only=1` to your request.
This approach performs the same checks as before (exists on PV2 and is not already handled), but does not set the notification to “handled.”
This allows you to cover Steps 1 and 2 without finalizing the notification as handled.
**Confirm Handling of the Notification**
To fulfill Step 3, the callback script retrieving the notification should print the predefined output, ensuring the content of the returned response is plain text: //*NOTIFIED*//.
===== 3. Handling Notifications Without Using the PV2 Endpoint
In this case, all required steps are handled on the partner's side.
**Verify the Notification**
To handle notifications of this type, you need to define a verification secret string. This value (e.g., an MD5 result) must be configured on the PV2 side (in the notification URL settings) and will be used to generate an extra hash that is appended to the notification.
A sample structure for the notification object:
```
{
"command": "...",
"hash": "....",
"data": {
...
},
"verify": "f75e721c6ff19ffcfd060a7d0ff02424407eb6a832d29196969d6bf844562571"
}
```
If the verify key exists, you need to generate your own verification hash on the partner side. To do this, use the following:
```
hash_hmac('sha256', json_encode($notification), $secretKey);
```
where $notification is an array built from the passed notification data:
```
$notification = [
'command' => $command,
'hash' => $hash,
'data' => $data
];
```
$secretKey is your verification secret.
The resulting hash should match the verify value passed in the notification. If they match, the notification is confirmed as coming from the PV2 app.
**Check if the Notification Has Been Handled**
On the partner's side, you need to implement a mechanism to track successfully processed hashes (e.g., an additional database table).
**Confirm Handling of the Notification**
You can use the same mechanism as described in Handling Notifications Using the PV2 Endpoint with the verify-only Flag. When a notification is successfully handled, print the predefined output: //*NOTIFIED*//.
===== 4. Asynchronous Notification Processing
To build an asynchronous solution using the `notification.hash.validation` endpoint:
The callback URL should add the notification to an internal async mechanism and return a blank output.
A consumer process that performs the actual processing should call notification.hash.validation without the verify-only flag.
Note: This approach introduces a potential risk due to the time gap between receiving the notification and running the processing script. To mitigate this, consider using an additional table to manage processing hashes.
**bold text**
=== List of notifications
[[ public/payment/partners/notifications/#transaction-success | transaction.success ]]
[[ public/payment/partners/notifications/#transaction-failed | transaction.failed ]]
[[ public/payment/partners/notifications/#transaction-change | transaction.change ]]
[[ public/payment/partners/notifications/#subscription-created | subscription.created ]]
[[ public/payment/partners/notifications/#subscription-trial | subscription.trial ]]
[[ public/payment/partners/notifications/#subscription-stopped | subscription.stopped ]]
[[ public/payment/partners/notifications/#subscription-suspended | subscription.suspended ]]
[[ public/payment/partners/notifications/#subscription-rebill | subscription.rebill ]]
[[ public/payment/partners/notifications/#subscription-completed | subscription.completed ]]
[[ public/payment/partners/notifications/#subscription-change | subscription.change ]]
------
PV2 is sending notifications to our partners regarding various actions on PV2. Notifications are always sent to the same URL defined for each partner along with hash and other related data. If partner doesn't respond to notification, PV2 will try to resend it.
Generally notifications will be sent in this format:
<table>
<tr>
<th>Param Name</th><th>Type</th><th>Description</th>
</tr>
<tr>
<td>command</td><td>string</td><td>The command that needs to be executed</td>
</tr>
<tr>
<td>hash</td><td>string</td><td>Hash</td>
</tr>
<tr>
<td>data</td><td>string</td><td>json encoded string with data array</td>
</tr>
</table>
When partner receives a notification the next step should be confirmation. There are two ways to do that.
- [[public/payment/partners/apidocs/notifications.hash.validate|notifications.hash.validate]] api call (async) by sending received hash back
- return a given string '//*NOTIFIED*//' as a result of notification request (http code must be 200)
For non confirmed notifications the resend mechanism will retry notification according to below schedule:
# After 1 minute
# After 5 minutes
# After 15 minutes
# After 30 minutes
# After 30 minutes
notifications.hash.validate call also has another important purpose, so partners can validate if the notification actually came from us.
This is list of notifications which will be send out.
= transaction.success
Sent in case of successful transaction.
Data array (json encoded)
<table>
<tr>
<th>Param Name</th><th>Type</th><th>Description</th>
</tr>
<tr><td>tran_id</td><td>int</td><td>**Transaction** ID</td></tr>
<tr><td>ptnr_id</td><td>int</td><td>**Partner** ID</td></tr>
<tr><td>ppac_id</td><td>int</td><td>**Payment Processor Account** ID</td></tr>
<tr><td>order_id</td><td>int</td><td>**Order** ID</td></tr>
<tr><td>ccdt_id</td><td>int</td><td>Credit Card Details ID</td></tr>
<tr><td>transaction_type</td><td>string</td><td>Transaction Type. Values: `s` (sale), `a` (auth), `r` (refund), `c` (chargeback), `f` (fake)</td></tr>
<tr><td>amount</td><td>string</td><td>Amount</td></tr>
<tr><td>currency</td><td>string</td><td>Currency (3 Letter ISO Code)</td></tr>
<tr><td>description</td><td>string</td><td>Description</td></tr>
<tr><td>status</td><td>string</td><td>Transaction status. Values: `failed`, `successful`</td></tr>
<tr><td>refunded_tran_id</td><td>int</td><td>Refunded **Transaction** ID</td></tr>
<tr><td>origin</td><td>string</td><td>Origin. Values: `direct`, `system`</td></tr>
<tr><td>ts</td><td>int</td><td>Timestamp</td></tr>
<tr><td>status_code</td><td>int</td><td>Status code</td></tr>
<tr><td>payment_code</td><td>int</td><td>[[ public/payment/partners/codes/ | Payment Code ]] (700 on success)</td></tr>
<tr><td>order_type</td><td>string</td><td>Order type. Values: `basic`, `xsale`</td></tr>
<tr><td>pp_id</td><td>int</td><td>**Payment Processor** ID</td></tr>
<tr><td>processor</td><td>string</td><td>**Payment Processor** abbreviation</td></tr>
<tr><td>user_id</td><td>int</td><td>User ID in **Payment Application**</td></tr>
<tr><td>tracking_user</td><td>int</td><td>User Identifier from **Partner**</td></tr>
<tr><td>tracking_tag</td><td>int</td><td>Tag ID from **Partner**</td></tr>
<tr><td>items</td><td>array</td><td>Array of items</td></tr>
<tr><td>merchant*</td><td>array</td><td>Array of fields that identify merchant account**</td></tr>
<tr><td>selected_cc_data*</td><td>array</td><td>Array of card data fields (ccdt_id, bin, ccnum_last4, exp_date, cc_type, cc_status) (with optional flag: marked_as_fraud)***</td></tr>
</table>
*//Processor dependant, may not be sent for all processors - currently only RocketGate and Payon use this field//
**//For RocketGate transaction, merchant is [merchant_id, merchant_account], for Payon it is [channel]//
**//For RocketGate transaction, only when using already existing card (rebills/rejoins)//
= transaction.failed
Sent in case of failed transaction.
Data array (json encoded)
<table>
<tr>
<th>Param Name</th><th>Type</th><th>Description</th>
</tr>
<tr><td>tran_id</td><td>int</td><td>**Transaction** ID</td></tr>
<tr><td>ptnr_id</td><td>int</td><td>**Partner** ID</td></tr>
<tr><td>ppac_id</td><td>int</td><td>**Payment Processor Account** ID</td></tr>
<tr><td>order_id</td><td>int</td><td>**Order** ID</td></tr>
<tr><td>ccdt_id</td><td>int</td><td>Credit Card Details ID</td></tr>
<tr><td>transaction_type</td><td>string</td><td>Transaction Type. Values: `s` (sale), `a` (auth), `r` (refund), `c` (chargeback), `f` (fake)</td></tr>
<tr><td>amount</td><td>string</td><td>Amount</td></tr>
<tr><td>currency</td><td>string</td><td>Currency (3 Letter ISO Code)</td></tr>
<tr><td>description</td><td>string</td><td>Description</td></tr>
<tr><td>status</td><td>string</td><td>Transaction status. Values: `failed`, `successful`</td></tr>
<tr><td>refunded_tran_id</td><td>int</td><td>Refunded **Transaction** ID</td></tr>
<tr><td>origin</td><td>string</td><td>Origin. Values: `direct`, `system`</td></tr>
<tr><td>ts</td><td>int</td><td>Timestamp</td></tr>
<tr><td>status_code</td><td>int</td><td>Status code</td></tr>
<tr><td>payment_code</td><td>int</td><td>[[ public/payment/partners/codes/ | Payment Code ]] (700 on success)</td></tr>
<tr><td>order_type</td><td>string</td><td>Order type. Values: `basic`, `xsale`</td></tr>
<tr><td>pp_id</td><td>int</td><td>**Payment Processor** ID</td></tr>
<tr><td>processor</td><td>string</td><td>**Payment Processor** abbreviation</td></tr>
<tr><td>user_id</td><td>int</td><td>User ID in **Payment Application**</td></tr>
<tr><td>tracking_user</td><td>int</td><td>User Identifier from **Partner**</td></tr>
<tr><td>tracking_tag</td><td>int</td><td>Tag ID from **Partner**</td></tr>
<tr><td>items</td><td>array</td><td>Array of items</td></tr>
<tr><td>merchant*</td><td>array</td><td>Array of fields that identify merchant account**</td></tr>
<tr><td>selected_cc_data*</td><td>array</td><td>Array of card data fields (ccdt_id, bin, ccnum_last4, exp_date, cc_type, cc_status) (with optional flag: marked_as_fraud)***</td></tr>
</table>
*//Processor dependant, may not be sent for all processors - currently only RocketGate and Payon use this field//
**//For RocketGate transaction, merchant is [merchant_id, merchant_account], for Payon it is [channel]//
**//For RocketGate transaction, only when using already existing card (rebills/rejoins)//
= transaction.change
Sent when transaction has been changed.
Possible cases when that might happen:
- [[ https://phab.dvipdev.com/w/public/payment/partners/apidocs/transaction.delete_chargeback | transaction.delete_chargeback ]]
- [[ https://phab.dvipdev.com/w/public/payment/partners/apidocs/transaction.chargeback | transaction.chargeback ]] refund for the same transaction already exists. so we update Refund -> Chargeback
Data array (json encoded)
<table>
<tr>
<th>Param Name</th><th>Type</th><th>Description</th>
</tr>
<tr><td>tran_id</td><td>int</td><td>**Transaction** ID</td></tr>
<tr><td>ptnr_id</td><td>int</td><td>**Partner** ID</td></tr>
<tr><td>ppac_id</td><td>int</td><td>**Payment Processor Account** ID</td></tr>
<tr><td>order_id</td><td>int</td><td>**Order** ID</td></tr>
<tr><td>ccdt_id</td><td>int</td><td>Credit Card Details ID</td></tr>
<tr><td>transaction_type</td><td>string</td><td>Transaction Type. Values: `s` (sale), `a` (auth), `r` (refund), `c` (chargeback), `f` (fake)</td></tr>
<tr><td>amount</td><td>string</td><td>Amount</td></tr>
<tr><td>currency</td><td>string</td><td>Currency (3 Letter ISO Code)</td></tr>
<tr><td>description</td><td>string</td><td>Description</td></tr>
<tr><td>status</td><td>string</td><td>Transaction status. Values: `failed`, `successful`</td></tr>
<tr><td>refunded_tran_id</td><td>int</td><td>Refunded **Transaction** ID</td></tr>
<tr><td>origin</td><td>string</td><td>Origin. Values: `direct`, `system`</td></tr>
<tr><td>ts</td><td>int</td><td>Timestamp</td></tr>
<tr><td>status_code</td><td>int</td><td>Status code</td></tr>
<tr><td>payment_code</td><td>int</td><td>[[ public/payment/partners/codes/ | Payment Code ]] (700 on success)</td></tr>
<tr><td>order_type</td><td>string</td><td>Order type. Values: `basic`, `xsale`</td></tr>
<tr><td>pp_id</td><td>int</td><td>**Payment Processor** ID</td></tr>
<tr><td>processor</td><td>string</td><td>**Payment Processor** abbreviation</td></tr>
<tr><td>user_id</td><td>int</td><td>User ID in **Payment Application**</td></tr>
<tr><td>tracking_user</td><td>int</td><td>User Identifier from **Partner**</td></tr>
<tr><td>tracking_tag</td><td>int</td><td>Tag ID from **Partner**</td></tr>
<tr><td>items</td><td>array</td><td>Array of items</td></tr>
</table>
*//Processor dependant, may not be sent for all processors - currently only RocketGate//
= subscription.created
Sent when subscription is successfully created __and__ subscription does not have trial.
Subscription does not have trial, if appropriate item passed in [[ public/payment/partners/apidocs/transaction.init/ | transaction.init ]] call, have empty value for parameter `trial_period`.
//(Minor use case: Also sent for manually rebilled subscriptions, in this case value of `rebill_period` for appropriate item in `transaction.init` call should be `-1`)//
Data array (json encoded)
<table>
<tr>
<th>Param Name</th><th>Type</th><th>Description</th>
</tr>
<tr><td>sub_id</td><td>int</td><td>Subscription ID</td></tr>
<tr><td>item_id</td><td>int</td><td>Item ID</td></tr>
<tr><td>status</td><td>string</td><td>Subscription status (s/b initial on create, rebill after 1st rebill)</td></tr>
<tr><td>start_ts</td><td>int</td><td>Start timestamp</td></tr>
<tr><td>change_ts</td><td>int</td><td>Change(edit) timestamp</td></tr>
<tr><td>end_ts</td><td>int</td><td>End timestamp</td></tr>
<tr><td>rebill_count</td><td>int</td><td>Number of recurring payments</td></tr>
<tr><td>last_rebill_ts</td><td>int</td><td>Last rebill ts</td></tr>
<tr><td>next_rebill_ts</td><td>int</td><td>Next rebill ts</td></tr>
<tr><td>next_rebill_amount</td><td>int</td><td>Next rebill amount</td></tr>
<tr><td>step_down</td><td>int</td><td>Step Down (charge amount reductions)</td></tr>
<tr><td>order_id</td><td>int</td><td>Order ID</td></tr>
<tr><td>description</td><td>int</td><td>Order Description</td></tr>
<tr><td>rebill_amount</td><td>int</td><td>Rebill amount (not including next one)</td></tr>
<tr><td>trial_unit</td><td>string</td><td>Trial Unit (day|week|month|year)</td></tr>
<tr><td>rebill_unit</td><td>string</td><td>Rebill Unit (day|week|month|year)</td></tr>
<tr><td>rebill_period</td><td>int</td><td>Rebill period</td></tr>
<tr><td>max_rebill_count</td><td>int</td><td>Max Rebill Count</td></tr>
<tr><td>trial_period</td><td>int</td><td>Trial period</td></tr>
<tr><td>tracking_item</td><td>int</td><td>Tracking item ID</td></tr>
<tr><td>pp_id</td><td>int</td><td>Payment Processor ID</td></tr>
<tr><td>user_id</td><td>int</td><td>PV2 user ID</td></tr>
<tr><td>hash</td><td>string</td><td>Hash</td></tr>
<tr><td>first_name</td><td>int</td><td>Customer's First Name</td></tr>
<tr><td>last_name</td><td>int</td><td>Customer's Last Name</td></tr>
<tr><td>ppac_id</td><td>int</td><td>Payment Processor Account ID</td></tr>
<tr><td>email</td><td>int</td><td>Customer's Email Address</td></tr>
<tr><td>ptnr_id</td><td>int</td><td>Partner ID</td></tr>
<tr><td>currency</td><td>string</td><td>Currency</td></tr>
<tr><td>tracking_tag</td><td>int</td><td>Tracking Tag param</td></tr>
<tr><td>ip</td><td>int</td><td>Customer's IP Address</td></tr>
<tr><td>order_type</td><td>int</td><td>Order type. Values: `basic`, `xsale`</td></tr>
<tr><td>tracking_user</td><td>int</td><td>User ID on partners' site</td></tr>
<tr><td>processor</td><td>int</td><td>Payment Processor's abreviation</td></tr>
<tr><td>tran_id*</td><td>int</td><td>Last Transaction's ID</td></tr>
</table>
//* Not present for all payment processors//
= subscription.trial
Sent when subscription is successfully created __and__ subscription does have trial.
Subscription does have trial, if appropriate item passed in [[ public/payment/partners/apidocs/transaction.init/ | transaction.init ]] call, have non-empty value for parameter `trial_period`.
<table>
<tr>
<th>Param Name</th><th>Type</th><th>Description</th>
</tr>
<tr><td>sub_id</td><td>int</td><td>Subscription ID</td></tr>
<tr><td>item_id</td><td>int</td><td>Item ID</td></tr>
<tr><td>status</td><td>string</td><td>Subscription status (s/b initial on create, rebill after 1st rebill)</td></tr>
<tr><td>start_ts</td><td>int</td><td>Start timestamp</td></tr>
<tr><td>change_ts</td><td>int</td><td>Change(edit) timestamp</td></tr>
<tr><td>end_ts</td><td>int</td><td>End timestamp</td></tr>
<tr><td>rebill_count</td><td>int</td><td>Number of recurring payments</td></tr>
<tr><td>last_rebill_ts</td><td>int</td><td>Last rebill ts</td></tr>
<tr><td>next_rebill_ts</td><td>int</td><td>Next rebill ts</td></tr>
<tr><td>next_rebill_amount</td><td>int</td><td>Next rebill amount</td></tr>
<tr><td>step_down</td><td>int</td><td>Step Down (charge amount reductions)</td></tr>
<tr><td>order_id</td><td>int</td><td>Order ID</td></tr>
<tr><td>description</td><td>int</td><td>Order Description</td></tr>
<tr><td>rebill_amount</td><td>int</td><td>Rebill amount (not including next one)</td></tr>
<tr><td>trial_unit</td><td>string</td><td>Trial Unit (day|week|month|year)</td></tr>
<tr><td>rebill_unit</td><td>string</td><td>Rebill Unit (day|week|month|year)</td></tr>
<tr><td>rebill_period</td><td>int</td><td>Rebill period</td></tr>
<tr><td>max_rebill_count</td><td>int</td><td>Max Rebill Count</td></tr>
<tr><td>trial_period</td><td>int</td><td>Trial period</td></tr>
<tr><td>tracking_item</td><td>int</td><td>Tracking item ID</td></tr>
<tr><td>pp_id</td><td>int</td><td>Payment Processor ID</td></tr>
<tr><td>user_id</td><td>int</td><td>PV2 user ID</td></tr>
<tr><td>hash</td><td>string</td><td>Hash</td></tr>
<tr><td>first_name</td><td>int</td><td>Customer's First Name</td></tr>
<tr><td>last_name</td><td>int</td><td>Customer's Last Name</td></tr>
<tr><td>ppac_id</td><td>int</td><td>Payment Processor Account ID</td></tr>
<tr><td>email</td><td>int</td><td>Customer's Email Address</td></tr>
<tr><td>ptnr_id</td><td>int</td><td>Partner ID</td></tr>
<tr><td>currency</td><td>string</td><td>Currency</td></tr>
<tr><td>tracking_tag</td><td>int</td><td>Tracking Tag param</td></tr>
<tr><td>ip</td><td>int</td><td>Customer's IP Address</td></tr>
<tr><td>order_type</td><td>int</td><td>Order type. Values: `basic`, `xsale`</td></tr>
<tr><td>tracking_user</td><td>int</td><td>User ID on partners' site</td></tr>
<tr><td>processor</td><td>int</td><td>Payment Processor's abreviation</td></tr>
<tr><td>tran_id*</td><td>int</td><td>Last Transaction's ID</td></tr>
</table>
//* Not present for all payment processors//
= subscription.stopped
Sent in case of stopped subscription (action initiated via api call)
Data array (json encoded)
<table>
<tr>
<th>Param Name</th><th>Type</th><th>Description</th>
</tr>
<tr><td>sub_id</td><td>int</td><td>Subscription ID</td></tr>
<tr><td>item_id</td><td>int</td><td>Item ID</td></tr>
<tr><td>status</td><td>string</td><td>Subscription status (s/b initial on create, rebill after 1st rebill)</td></tr>
<tr><td>start_ts</td><td>int</td><td>Start timestamp</td></tr>
<tr><td>change_ts</td><td>int</td><td>Change(edit) timestamp</td></tr>
<tr><td>end_ts</td><td>int</td><td>End timestamp</td></tr>
<tr><td>rebill_count</td><td>int</td><td>Number of recurring payments</td></tr>
<tr><td>last_rebill_ts</td><td>int</td><td>Last rebill ts</td></tr>
<tr><td>next_rebill_ts</td><td>int</td><td>Next rebill ts</td></tr>
<tr><td>next_rebill_amount</td><td>int</td><td>Next rebill amount</td></tr>
<tr><td>step_down</td><td>int</td><td>Step Down (charge amount reductions)</td></tr>
<tr><td>order_id</td><td>int</td><td>Order ID</td></tr>
<tr><td>description</td><td>int</td><td>Order Description</td></tr>
<tr><td>rebill_amount</td><td>int</td><td>Rebill amount (not including next one)</td></tr>
<tr><td>trial_unit</td><td>string</td><td>Trial Unit (day|week|month|year)</td></tr>
<tr><td>rebill_unit</td><td>string</td><td>Rebill Unit (day|week|month|year)</td></tr>
<tr><td>rebill_period</td><td>int</td><td>Rebill period</td></tr>
<tr><td>max_rebill_count</td><td>int</td><td>Max Rebill Count</td></tr>
<tr><td>trial_period</td><td>int</td><td>Trial period</td></tr>
<tr><td>tracking_item</td><td>int</td><td>Tracking item ID</td></tr>
<tr><td>pp_id</td><td>int</td><td>Payment Processor ID</td></tr>
<tr><td>user_id</td><td>int</td><td>PV2 user ID</td></tr>
<tr><td>hash</td><td>string</td><td>Hash</td></tr>
<tr><td>first_name</td><td>int</td><td>Customer's First Name</td></tr>
<tr><td>last_name</td><td>int</td><td>Customer's Last Name</td></tr>
<tr><td>ppac_id</td><td>int</td><td>Payment Processor Account ID</td></tr>
<tr><td>email</td><td>int</td><td>Customer's Email Address</td></tr>
<tr><td>ptnr_id</td><td>int</td><td>Partner ID</td></tr>
<tr><td>currency</td><td>string</td><td>Currency</td></tr>
<tr><td>tracking_tag</td><td>int</td><td>Tracking Tag param</td></tr>
<tr><td>ip</td><td>int</td><td>Customer's IP Address</td></tr>
<tr><td>order_type</td><td>int</td><td>Order type. Values: `basic`, `xsale`</td></tr>
<tr><td>tracking_user</td><td>int</td><td>User ID on partners' site</td></tr>
<tr><td>processor</td><td>int</td><td>Payment Processor's abreviation</td></tr>
<tr><td>is_cancel</td><td>boolean</td><td>s/b true</td></tr>
<tr><td>cancel_reason</td><td>string</td><td>Optional, not always sent. If it has value 'cancel_reason_rebill_bin_filter' it means that subscription was stopped because BIN used for purchase is not allowed to rebill.</td></tr>
</table>
= subscription.suspended
Sent in case of suspended subscription (usually happens when we can't rebill user after defined number of attempts)
Data array (json encoded)
<table>
<tr>
<th>Param Name</th><th>Type</th><th>Description</th>
</tr>
<tr><td>sub_id</td><td>int</td><td>Subscription ID</td></tr>
<tr><td>item_id</td><td>int</td><td>Item ID</td></tr>
<tr><td>status</td><td>string</td><td>Subscription status (s/b initial on create, rebill after 1st rebill)</td></tr>
<tr><td>start_ts</td><td>int</td><td>Start timestamp</td></tr>
<tr><td>change_ts</td><td>int</td><td>Change(edit) timestamp</td></tr>
<tr><td>end_ts</td><td>int</td><td>End timestamp</td></tr>
<tr><td>rebill_count</td><td>int</td><td>Number of recurring payments</td></tr>
<tr><td>last_rebill_ts</td><td>int</td><td>Last rebill ts</td></tr>
<tr><td>next_rebill_ts</td><td>int</td><td>Next rebill ts</td></tr>
<tr><td>next_rebill_amount</td><td>int</td><td>Next rebill amount</td></tr>
<tr><td>step_down</td><td>int</td><td>Step Down (charge amount reductions)</td></tr>
<tr><td>order_id</td><td>int</td><td>Order ID</td></tr>
<tr><td>description</td><td>int</td><td>Order Description</td></tr>
<tr><td>rebill_amount</td><td>int</td><td>Rebill amount (not including next one)</td></tr>
<tr><td>trial_unit</td><td>string</td><td>Trial Unit (day|week|month|year)</td></tr>
<tr><td>rebill_unit</td><td>string</td><td>Rebill Unit (day|week|month|year)</td></tr>
<tr><td>rebill_period</td><td>int</td><td>Rebill period</td></tr>
<tr><td>max_rebill_count</td><td>int</td><td>Max Rebill Count</td></tr>
<tr><td>trial_period</td><td>int</td><td>Trial period</td></tr>
<tr><td>tracking_item</td><td>int</td><td>Tracking item ID</td></tr>
<tr><td>pp_id</td><td>int</td><td>Payment Processor ID</td></tr>
<tr><td>user_id</td><td>int</td><td>PV2 user ID</td></tr>
<tr><td>hash</td><td>string</td><td>Hash</td></tr>
<tr><td>first_name</td><td>int</td><td>Customer's First Name</td></tr>
<tr><td>last_name</td><td>int</td><td>Customer's Last Name</td></tr>
<tr><td>ppac_id</td><td>int</td><td>Payment Processor Account ID</td></tr>
<tr><td>email</td><td>int</td><td>Customer's Email Address</td></tr>
<tr><td>ptnr_id</td><td>int</td><td>Partner ID</td></tr>
<tr><td>currency</td><td>string</td><td>Currency</td></tr>
<tr><td>tracking_tag</td><td>int</td><td>Tracking Tag param</td></tr>
<tr><td>ip</td><td>int</td><td>Customer's IP Address</td></tr>
<tr><td>order_type</td><td>int</td><td>Order type. Values: `basic`, `xsale`</td></tr>
<tr><td>tracking_user</td><td>int</td><td>User ID on partners' site</td></tr>
<tr><td>processor</td><td>int</td><td>Payment Processor's abreviation</td></tr>
</table>
= subscription.rebill
Sent after successfully made rebill. It will be sent right after transaction.success
Data array (json encoded)
<table>
<tr>
<th>Param Name</th><th>Type</th><th>Description</th>
</tr>
<tr><td>sub_id</td><td>int</td><td>Subscription ID</td></tr>
<tr><td>item_id</td><td>int</td><td>Item ID</td></tr>
<tr><td>status</td><td>string</td><td>Subscription status (s/b initial on create, rebill after 1st rebill)</td></tr>
<tr><td>start_ts</td><td>int</td><td>Start timestamp</td></tr>
<tr><td>change_ts</td><td>int</td><td>Change(edit) timestamp</td></tr>
<tr><td>end_ts</td><td>int</td><td>End timestamp</td></tr>
<tr><td>rebill_count</td><td>int</td><td>Number of recurring payments</td></tr>
<tr><td>last_rebill_ts</td><td>int</td><td>Last rebill ts</td></tr>
<tr><td>next_rebill_ts</td><td>int</td><td>Next rebill ts</td></tr>
<tr><td>next_rebill_amount</td><td>int</td><td>Next rebill amount</td></tr>
<tr><td>step_down</td><td>int</td><td>Step Down (charge amount reductions)</td></tr>
<tr><td>order_id</td><td>int</td><td>Order ID</td></tr>
<tr><td>description</td><td>int</td><td>Order Description</td></tr>
<tr><td>rebill_amount</td><td>int</td><td>Rebill amount (not including next one)</td></tr>
<tr><td>trial_unit</td><td>string</td><td>Trial Unit (day|week|month|year)</td></tr>
<tr><td>rebill_unit</td><td>string</td><td>Rebill Unit (day|week|month|year)</td></tr>
<tr><td>rebill_period</td><td>int</td><td>Rebill period</td></tr>
<tr><td>max_rebill_count</td><td>int</td><td>Max Rebill Count</td></tr>
<tr><td>trial_period</td><td>int</td><td>Trial period</td></tr>
<tr><td>tracking_item</td><td>int</td><td>Tracking item ID</td></tr>
<tr><td>pp_id</td><td>int</td><td>Payment Processor ID</td></tr>
<tr><td>user_id</td><td>int</td><td>PV2 user ID</td></tr>
<tr><td>hash</td><td>string</td><td>Hash</td></tr>
<tr><td>first_name</td><td>int</td><td>Customer's First Name</td></tr>
<tr><td>last_name</td><td>int</td><td>Customer's Last Name</td></tr>
<tr><td>ppac_id</td><td>int</td><td>Payment Processor Account ID</td></tr>
<tr><td>email</td><td>int</td><td>Customer's Email Address</td></tr>
<tr><td>ptnr_id</td><td>int</td><td>Partner ID</td></tr>
<tr><td>currency</td><td>string</td><td>Currency</td></tr>
<tr><td>tracking_tag</td><td>int</td><td>Tracking Tag param</td></tr>
<tr><td>ip</td><td>int</td><td>Customer's IP Address</td></tr>
<tr><td>order_type</td><td>int</td><td>Order type. Values: `basic`, `xsale`</td></tr>
<tr><td>tracking_user</td><td>int</td><td>User ID on partners' site</td></tr>
<tr><td>processor</td><td>int</td><td>Payment Processor's abreviation</td></tr>
<tr><td>tran_id*</td><td>int</td><td>Last Transaction's ID</td></tr>
</table>
//* Not present for all payment processors//
= subscription.completed
Sent after completed subscription (happens only on subs with limited number of rebills).
Data array (json encoded)
<table>
<tr>
<th>Param Name</th><th>Type</th><th>Description</th>
</tr>
<tr><td>sub_id</td><td>int</td><td>Subscription ID</td></tr>
<tr><td>item_id</td><td>int</td><td>Item ID</td></tr>
<tr><td>status</td><td>string</td><td>Subscription status (s/b initial on create, rebill after 1st rebill)</td></tr>
<tr><td>start_ts</td><td>int</td><td>Start timestamp</td></tr>
<tr><td>change_ts</td><td>int</td><td>Change(edit) timestamp</td></tr>
<tr><td>end_ts</td><td>int</td><td>End timestamp</td></tr>
<tr><td>rebill_count</td><td>int</td><td>Number of recurring payments</td></tr>
<tr><td>last_rebill_ts</td><td>int</td><td>Last rebill ts</td></tr>
<tr><td>next_rebill_ts</td><td>int</td><td>Next rebill ts</td></tr>
<tr><td>next_rebill_amount</td><td>int</td><td>Next rebill amount</td></tr>
<tr><td>step_down</td><td>int</td><td>Step Down (charge amount reductions)</td></tr>
<tr><td>order_id</td><td>int</td><td>Order ID</td></tr>
<tr><td>description</td><td>int</td><td>Order Description</td></tr>
<tr><td>rebill_amount</td><td>int</td><td>Rebill amount (not including next one)</td></tr>
<tr><td>trial_unit</td><td>string</td><td>Trial Unit (day|week|month|year)</td></tr>
<tr><td>rebill_unit</td><td>string</td><td>Rebill Unit (day|week|month|year)</td></tr>
<tr><td>rebill_period</td><td>int</td><td>Rebill period</td></tr>
<tr><td>max_rebill_count</td><td>int</td><td>Max Rebill Count</td></tr>
<tr><td>trial_period</td><td>int</td><td>Trial period</td></tr>
<tr><td>tracking_item</td><td>int</td><td>Tracking item ID</td></tr>
<tr><td>pp_id</td><td>int</td><td>Payment Processor ID</td></tr>
<tr><td>user_id</td><td>int</td><td>PV2 user ID</td></tr>
<tr><td>hash</td><td>string</td><td>Hash</td></tr>
<tr><td>first_name</td><td>int</td><td>Customer's First Name</td></tr>
<tr><td>last_name</td><td>int</td><td>Customer's Last Name</td></tr>
<tr><td>ppac_id</td><td>int</td><td>Payment Processor Account ID</td></tr>
<tr><td>email</td><td>int</td><td>Customer's Email Address</td></tr>
<tr><td>ptnr_id</td><td>int</td><td>Partner ID</td></tr>
<tr><td>currency</td><td>string</td><td>Currency</td></tr>
<tr><td>tracking_tag</td><td>int</td><td>Tracking Tag param</td></tr>
<tr><td>ip</td><td>int</td><td>Customer's IP Address</td></tr>
<tr><td>order_type</td><td>int</td><td>Order type. Values: `basic`, `xsale`</td></tr>
<tr><td>tracking_user</td><td>int</td><td>User ID on partners' site</td></tr>
<tr><td>processor</td><td>int</td><td>Payment Processor's abreviation</td></tr>
</table>
= subscription.change
Sent in when subscription is changed (action initiated via `subscription.change` api call)
Data array (json encoded)
<table>
<tr>
<th>Param Name</th><th>Type</th><th>Description</th>
</tr>
<tr><td>sub_id</td><td>int</td><td>Subscription ID</td></tr>
<tr><td>item_id</td><td>int</td><td>Item ID</td></tr>
<tr><td>status</td><td>string</td><td>Subscription status (s/b initial on create, rebill after 1st rebill)</td></tr>
<tr><td>start_ts</td><td>int</td><td>Start timestamp</td></tr>
<tr><td>change_ts</td><td>int</td><td>Change(edit) timestamp</td></tr>
<tr><td>end_ts</td><td>int</td><td>End timestamp</td></tr>
<tr><td>rebill_count</td><td>int</td><td>Number of recurring payments</td></tr>
<tr><td>last_rebill_ts</td><td>int</td><td>Last rebill ts</td></tr>
<tr><td>next_rebill_ts</td><td>int</td><td>Next rebill ts</td></tr>
<tr><td>next_rebill_amount</td><td>int</td><td>Next rebill amount</td></tr>
<tr><td>step_down</td><td>int</td><td>Step Down (charge amount reductions)</td></tr>
<tr><td>order_id</td><td>int</td><td>Order ID</td></tr>
<tr><td>description</td><td>int</td><td>Order Description</td></tr>
<tr><td>rebill_amount</td><td>int</td><td>Rebill amount (not including next one)</td></tr>
<tr><td>trial_unit</td><td>string</td><td>Trial Unit (day|week|month|year)</td></tr>
<tr><td>rebill_unit</td><td>string</td><td>Rebill Unit (day|week|month|year)</td></tr>
<tr><td>rebill_period</td><td>int</td><td>Rebill period</td></tr>
<tr><td>max_rebill_count</td><td>int</td><td>Max Rebill Count</td></tr>
<tr><td>trial_period</td><td>int</td><td>Trial period</td></tr>
<tr><td>tracking_item</td><td>int</td><td>Tracking item ID</td></tr>
<tr><td>pp_id</td><td>int</td><td>Payment Processor ID</td></tr>
<tr><td>user_id</td><td>int</td><td>PV2 user ID</td></tr>
<tr><td>hash</td><td>string</td><td>Hash</td></tr>
<tr><td>first_name</td><td>int</td><td>Customer's First Name</td></tr>
<tr><td>last_name</td><td>int</td><td>Customer's Last Name</td></tr>
<tr><td>ppac_id</td><td>int</td><td>Payment Processor Account ID</td></tr>
<tr><td>email</td><td>int</td><td>Customer's Email Address</td></tr>
<tr><td>ptnr_id</td><td>int</td><td>Partner ID</td></tr>
<tr><td>currency</td><td>string</td><td>Currency</td></tr>
<tr><td>tracking_tag</td><td>int</td><td>Tracking Tag param</td></tr>
<tr><td>ip</td><td>int</td><td>Customer's IP Address</td></tr>
<tr><td>order_type</td><td>int</td><td>Order type. Values: `basic`, `xsale`</td></tr>
<tr><td>tracking_user</td><td>int</td><td>User ID on partners' site</td></tr>
<tr><td>processor</td><td>int</td><td>Payment Processor's abreviation</td></tr>
</table>
= Content= Partner Notifications
=== Handling notification on partner side
Handling retrieved notifications involves the following steps:
1. Verify if the notification has been sent by PV2.
2. Check if the notification has already been handled.
3. Confirm the handling of the given notification.
==== Ways to Handle Notifications
===== 1. Handling Notifications Using the PV2 Endpoint (Not Recommended)
To meet all requirements, you can call the `notification.hash.validation` endpoint. This endpoint requires the hash of the given notification as an argument. It will return success only if:
- The given hash exists on the PV2 side, and
- The notification has a status of “not handled.”
- At the same time, the endpoint will mark the notification as “handled.”
**Why is this approach not recommended?**
The processes of verification (Step 1) and handling confirmation (Step 2) cannot be separated. If you simply want to verify the notification, it will still be marked as “handled.” This can cause issues because, in the event of an exception during processing, the PV2 system will never reattempt the notification (since handled = 1).
===== 2. Handling Notifications Using the PV2 Endpoint with the verify-only Flag
**Verify the Notification & Check if the Notification Has Been Handled**
In this case, you use the `notification.hash.validation` endpoint with an additional verify-only flag. To do this, append `verify-only=1` to your request.
This approach performs the same checks as before (exists on PV2 and is not already handled), but does not set the notification to “handled.”
This allows you to cover Steps 1 and 2 without finalizing the notification as handled.
**Confirm Handling of the Notification**
To fulfill Step 3, the callback script retrieving the notification should print the predefined output, ensuring the content of the returned response is plain text: //*NOTIFIED*//.
===== 3. Handling Notifications Without Using the PV2 Endpoint
In this case, all required steps are handled on the partner's side.
**Verify the Notification**
To handle notifications of this type, you need to define a verification secret string. This value (e.g., an MD5 result) must be configured on the PV2 side (in the notification URL settings) and will be used to generate an extra hash that is appended to the notification.
A sample structure for the notification object:
```
{
"command": "...",
"hash": "....",
"data": {
...
},
"verify": "f75e721c6ff19ffcfd060a7d0ff02424407eb6a832d29196969d6bf844562571"
}
```
If the verify key exists, you need to generate your own verification hash on the partner side. To do this, use the following:
```
hash_hmac('sha256', json_encode($notification), $secretKey);
```
where $notification is an array built from the passed notification data:
```
$notification = [
'command' => $command,
'hash' => $hash,
'data' => $data
];
```
$secretKey is your verification secret.
The resulting hash should match the verify value passed in the notification. If they match, the notification is confirmed as coming from the PV2 app.
**Check if the Notification Has Been Handled**
On the partner's side, you need to implement a mechanism to track successfully processed hashes (e.g., an additional database table).
**Confirm Handling of the Notification**
You can use the same mechanism as described in Handling Notifications Using the PV2 Endpoint with the verify-only Flag. When a notification is successfully handled, print the predefined output: //*NOTIFIED*//.
===== 4. Asynchronous Notification Processing
To build an asynchronous solution using the `notification.hash.validation` endpoint:
The callback URL should add the notification to an internal async mechanism and return a blank output.
A consumer process that performs the actual processing should call notification.hash.validation without the verify-only flag.
Note: This approach introduces a potential risk due to the time gap between receiving the notification and running the processing script. To mitigate this, consider using an additional table to manage processing hashes.
**bold text**
=== List of notifications
[[ public/payment/partners/notifications/#transaction-success | transaction.success ]]
[[ public/payment/partners/notifications/#transaction-failed | transaction.failed ]]
[[ public/payment/partners/notifications/#transaction-change | transaction.change ]]
[[ public/payment/partners/notifications/#subscription-created | subscription.created ]]
[[ public/payment/partners/notifications/#subscription-trial | subscription.trial ]]
[[ public/payment/partners/notifications/#subscription-stopped | subscription.stopped ]]
[[ public/payment/partners/notifications/#subscription-suspended | subscription.suspended ]]
[[ public/payment/partners/notifications/#subscription-rebill | subscription.rebill ]]
[[ public/payment/partners/notifications/#subscription-completed | subscription.completed ]]
[[ public/payment/partners/notifications/#subscription-change | subscription.change ]]
[[ public/payment/partners/notifications/#subscriptions-prerebill | subscriptions.prerebill ]]
------
PV2 is sending notifications to our partners regarding various actions on PV2. Notifications are always sent to the same URL defined for each partner along with hash and other related data. If partner doesn't respond to notification, PV2 will try to resend it.
Generally notifications will be sent in this format:
<table>
<tr>
<th>Param Name</th><th>Type</th><th>Description</th>
</tr>
<tr>
<td>command</td><td>string</td><td>The command that needs to be executed</td>
</tr>
<tr>
<td>hash</td><td>string</td><td>Hash</td>
</tr>
<tr>
<td>data</td><td>string</td><td>json encoded string with data array</td>
</tr>
</table>
AftWhen partner receivinges a notification partnerthe next step should respond withbe confirmation. There are two ways to do that.
- [[public/payment/partners/apidocs/notifications.hash.validate|notifications.hash.validate]] api call (async) by sending received hash back, otherwise notification will be resent with this schedul
- return a given string '//*NOTIFIED*//' as a result of notification request (http code must be 200)
For non confirmed notifications the resend mechanism will retry notification according to below schedule:
# After 1 minute
# After 5 minutes
# After 15 minutes
# After 30 minutes
# After 30 minutes
notifications.hash.validate call also has another important purpose, so partners can validate if the notification actually came from us.
This is list of notifications which will be send out.
= transaction.success
Sent in case of successful transaction.
Data array (json encoded)
<table>
<tr>
<th>Param Name</th><th>Type</th><th>Description</th>
</tr>
<tr><td>tran_id</td><td>int</td><td>**Transaction** ID</td></tr>
<tr><td>ptnr_id</td><td>int</td><td>**Partner** ID</td></tr>
<tr><td>ppac_id</td><td>int</td><td>**Payment Processor Account** ID</td></tr>
<tr><td>order_id</td><td>int</td><td>**Order** ID</td></tr>
<tr><td>ccdt_id</td><td>int</td><td>Credit Card Details ID</td></tr>
<tr><td>transaction_type</td><td>string</td><td>Transaction Type. Values: `s` (sale), `a` (auth), `r` (refund), `c` (chargeback), `f` (fake)</td></tr>
<tr><td>amount</td><td>string</td><td>Amount</td></tr>
<tr><td>currency</td><td>string</td><td>Currency (3 Letter ISO Code)</td></tr>
<tr><td>description</td><td>string</td><td>Description</td></tr>
<tr><td>status</td><td>string</td><td>Transaction status. Values: `failed`, `successful`</td></tr>
<tr><td>refunded_tran_id</td><td>int</td><td>Refunded **Transaction** ID</td></tr>
<tr><td>origin</td><td>string</td><td>Origin. Values: `direct`, `system`</td></tr>
<tr><td>ts</td><td>int</td><td>Timestamp</td></tr>
<tr><td>status_code</td><td>int</td><td>Status code</td></tr>
<tr><td>payment_code</td><td>int</td><td>[[ public/payment/partners/codes/ | Payment Code ]] (700 on success)</td></tr>
<tr><td>order_type</td><td>string</td><td>Order type. Values: `basic`, `xsale`</td></tr>
<tr><td>pp_id</td><td>int</td><td>**Payment Processor** ID</td></tr>
<tr><td>processor</td><td>string</td><td>**Payment Processor** abbreviation</td></tr>
<tr><td>user_id</td><td>int</td><td>User ID in **Payment Application**</td></tr>
<tr><td>tracking_user</td><td>int</td><td>User Identifier from **Partner**</td></tr>
<tr><td>tracking_tag</td><td>int</td><td>Tag ID from **Partner**</td></tr>
<tr><td>items</td><td>array</td><td>Array of items</td></tr>
<tr><td>merchant*</td><td>array</td><td>Array of fields that identify merchant account**</td></tr>
<tr><td>selected_cc_data*</td><td>array</td><td>Array of card data fields (ccdt_id, bin, ccnum_last4, exp_date, cc_type, cc_status) (with optional flag: marked_as_fraud)***</td></tr>
</table>
*//Processor dependant, may not be sent for all processors - currently only RocketGate and Payon use this field//
**//For RocketGate transaction, merchant is [merchant_id, merchant_account], for Payon it is [channel]//
**//For RocketGate transaction, only when using already existing card (rebills/rejoins)//
= transaction.failed
Sent in case of failed transaction.
Data array (json encoded)
<table>
<tr>
<th>Param Name</th><th>Type</th><th>Description</th>
</tr>
<tr><td>tran_id</td><td>int</td><td>**Transaction** ID</td></tr>
<tr><td>ptnr_id</td><td>int</td><td>**Partner** ID</td></tr>
<tr><td>ppac_id</td><td>int</td><td>**Payment Processor Account** ID</td></tr>
<tr><td>order_id</td><td>int</td><td>**Order** ID</td></tr>
<tr><td>ccdt_id</td><td>int</td><td>Credit Card Details ID</td></tr>
<tr><td>transaction_type</td><td>string</td><td>Transaction Type. Values: `s` (sale), `a` (auth), `r` (refund), `c` (chargeback), `f` (fake)</td></tr>
<tr><td>amount</td><td>string</td><td>Amount</td></tr>
<tr><td>currency</td><td>string</td><td>Currency (3 Letter ISO Code)</td></tr>
<tr><td>description</td><td>string</td><td>Description</td></tr>
<tr><td>status</td><td>string</td><td>Transaction status. Values: `failed`, `successful`</td></tr>
<tr><td>refunded_tran_id</td><td>int</td><td>Refunded **Transaction** ID</td></tr>
<tr><td>origin</td><td>string</td><td>Origin. Values: `direct`, `system`</td></tr>
<tr><td>ts</td><td>int</td><td>Timestamp</td></tr>
<tr><td>status_code</td><td>int</td><td>Status code</td></tr>
<tr><td>payment_code</td><td>int</td><td>[[ public/payment/partners/codes/ | Payment Code ]] (700 on success)</td></tr>
<tr><td>order_type</td><td>string</td><td>Order type. Values: `basic`, `xsale`</td></tr>
<tr><td>pp_id</td><td>int</td><td>**Payment Processor** ID</td></tr>
<tr><td>processor</td><td>string</td><td>**Payment Processor** abbreviation</td></tr>
<tr><td>user_id</td><td>int</td><td>User ID in **Payment Application**</td></tr>
<tr><td>tracking_user</td><td>int</td><td>User Identifier from **Partner**</td></tr>
<tr><td>tracking_tag</td><td>int</td><td>Tag ID from **Partner**</td></tr>
<tr><td>items</td><td>array</td><td>Array of items</td></tr>
<tr><td>merchant*</td><td>array</td><td>Array of fields that identify merchant account**</td></tr>
<tr><td>selected_cc_data*</td><td>array</td><td>Array of card data fields (ccdt_id, bin, ccnum_last4, exp_date, cc_type, cc_status) (with optional flag: marked_as_fraud)***</td></tr>
</table>
*//Processor dependant, may not be sent for all processors - currently only RocketGate and Payon use this field//
**//For RocketGate transaction, merchant is [merchant_id, merchant_account], for Payon it is [channel]//
**//For RocketGate transaction, only when using already existing card (rebills/rejoins)//
= transaction.change
Sent when transaction has been changed.
Possible cases when that might happen:
- [[ https://phab.dvipdev.com/w/public/payment/partners/apidocs/transaction.delete_chargeback | transaction.delete_chargeback ]]
- [[ https://phab.dvipdev.com/w/public/payment/partners/apidocs/transaction.chargeback | transaction.chargeback ]] refund for the same transaction already exists. so we update Refund -> Chargeback
Data array (json encoded)
<table>
<tr>
<th>Param Name</th><th>Type</th><th>Description</th>
</tr>
<tr><td>tran_id</td><td>int</td><td>**Transaction** ID</td></tr>
<tr><td>ptnr_id</td><td>int</td><td>**Partner** ID</td></tr>
<tr><td>ppac_id</td><td>int</td><td>**Payment Processor Account** ID</td></tr>
<tr><td>order_id</td><td>int</td><td>**Order** ID</td></tr>
<tr><td>ccdt_id</td><td>int</td><td>Credit Card Details ID</td></tr>
<tr><td>transaction_type</td><td>string</td><td>Transaction Type. Values: `s` (sale), `a` (auth), `r` (refund), `c` (chargeback), `f` (fake)</td></tr>
<tr><td>amount</td><td>string</td><td>Amount</td></tr>
<tr><td>currency</td><td>string</td><td>Currency (3 Letter ISO Code)</td></tr>
<tr><td>description</td><td>string</td><td>Description</td></tr>
<tr><td>status</td><td>string</td><td>Transaction status. Values: `failed`, `successful`</td></tr>
<tr><td>refunded_tran_id</td><td>int</td><td>Refunded **Transaction** ID</td></tr>
<tr><td>origin</td><td>string</td><td>Origin. Values: `direct`, `system`</td></tr>
<tr><td>ts</td><td>int</td><td>Timestamp</td></tr>
<tr><td>status_code</td><td>int</td><td>Status code</td></tr>
<tr><td>payment_code</td><td>int</td><td>[[ public/payment/partners/codes/ | Payment Code ]] (700 on success)</td></tr>
<tr><td>order_type</td><td>string</td><td>Order type. Values: `basic`, `xsale`</td></tr>
<tr><td>pp_id</td><td>int</td><td>**Payment Processor** ID</td></tr>
<tr><td>processor</td><td>string</td><td>**Payment Processor** abbreviation</td></tr>
<tr><td>user_id</td><td>int</td><td>User ID in **Payment Application**</td></tr>
<tr><td>tracking_user</td><td>int</td><td>User Identifier from **Partner**</td></tr>
<tr><td>tracking_tag</td><td>int</td><td>Tag ID from **Partner**</td></tr>
<tr><td>items</td><td>array</td><td>Array of items</td></tr>
</table>
*//Processor dependant, may not be sent for all processors - currently only RocketGate//
= subscription.created
Sent in case of successfully created subscriptionwhen subscription is successfully created __and__ subscription does not have trial.
Subscription does not have trial, if appropriate item passed in [[ public/payment/partners/apidocs/transaction.init/ | transaction.init ]] call, have empty value for parameter `trial_period`.
//(Minor use case: Also sent for manually rebilled subscriptions, in this case value of `rebill_period` for appropriate item in `transaction.init` call should be `-1`)//
Data array (json encoded)
<table>
<tr>
<th>Param Name</th><th>Type</th><th>Description</th>
</tr>
<tr><td>sub_id</td><td>int</td><td>Subscription ID</td></tr>
<tr><td>item_id</td><td>int</td><td>Item ID</td></tr>
<tr><td>status</td><td>string</td><td>Subscription status (s/b initial on create, rebill after 1st rebill)</td></tr>
<tr><td>start_ts</td><td>int</td><td>Start timestamp</td></tr>
<tr><td>user_idchange_ts</td><td>int</td><td>PV2 user IDChange(edit) timestamp</td></tr>
<tr><td>tracking_userend_ts</td><td>int</td><td>User ID on partners' siteEnd timestamp</td></tr>
<tr><td>ptnr_idrebill_count</td><td>int</td><td>Partner IDNumber of recurring payments</td></tr>
<tr><td>tracking_taglast_rebill_ts</td><td>int</td><td>Tracking Tag paramLast rebill ts</td></tr>
<tr><td>currencynext_rebill_ts</td><td>stringint</td><td>CurrencyNext rebill ts</td></tr>
<tr><td>hashnext_rebill_amount</td><td>stringint</td><td>HashNext rebill amount</td></tr>
<tr><td>pp_namestep_down</td><td>stringint</td><td>PP NameStep Down (charge amount reductions)</td></tr>
<tr><td>trial_unitorder_id</td><td>stringint</td><td>Trial Unit (day|week|month|year)Order ID</td></tr>
<tr><td>trial_period</td><td>int</td><td>Trial perioddescription</td><td>int</td><td>Order Description</td></tr>
<tr><td>rebill_amount</td><td>int</td><td>Rebill amount (not including next one)</td></tr>
<tr><td>trial_unit</td><td>string</td><td>Trial Unit (day|week|month|year)</td></tr>
<tr><td>rebill_unit</td><td>string</td><td>Rebill Unit (day|week|month|year)</td></tr>
<tr><td>rebill_period</td><td>int</td><td>Rebill period</td></tr>
<tr><td>max_rebill_count</td><td>int</td><td>Max Rebill Count</td></tr>
<tr><td>trial_period</td><td>int</td><td>Trial period</td></tr>
<tr><td>tracking_item</td><td>int</td><td>Tracking item ID</td></tr>
<tr><td>next_rebill_tspp_id</td><td>int</td><td>Next rebill tsPayment Processor ID</td></tr>
<tr><td>last_rebill_ts</td><td>int</td><td>Last rebill tsuser_id</td><td>int</td><td>PV2 user ID</td></tr>
<tr><td>hash</td><td>string</td><td>Hash</td></tr>
<tr><td>first_name</td><td>int</td><td>Customer's First Name</td></tr>
<tr><td>last_name</td><td>int</td><td>Customer's Last Name</td></tr>
<tr><td>ppac_id</td><td>int</td><td>Payment Processor Account ID</td></tr>
<tr><td>email</td><td>int</td><td>Customer's Email Address</td></tr>
<tr><td>ptnr_id</td><td>int</td><td>Partner ID</td></tr>
<tr><td>currency</td><td>string</td><td>Currency</td></tr>
<tr><td>tracking_tag</td><td>int</td><td>Tracking Tag param</td></tr>
<tr><td>ip</td><td>int</td><td>Customer's IP Address</td></tr>
<tr><td>order_type</td><td>int</td><td>Order type. Values: `basic`, `xsale`</td></tr>
<tr><td>tracking_user</td><td>int</td><td>User ID on partners' site</td></tr>
<tr><td>processor</td><td>int</td><td>Payment Processor's abreviation</td></tr>
<tr><td>tran_id*</td><td>int</td><td>Last Transaction's ID</td></tr>
</table>
//* Not present for all payment processors//
= subscription.trial
Sent in case ofwhen subscription is successfully createdd __and__ subscription
Data array (json encoded) does have trial.
Subscription does have trial, if appropriate item passed in [[ public/payment/partners/apidocs/transaction.init/ | transaction.init ]] call, have non-empty value for parameter `trial_period`.
<table>
<tr>
<th>Param Name</th><th>Type</th><th>Description</th>
</tr>
<tr><td>sub_id</td><td>int</td><td>Subscription ID</td></tr>
<tr><td>item_id</td><td>int</td><td>Item ID</td></tr>
<tr><td>status</td><td>string</td><td>Subscription status (s/b initial on create, rebill after 1st rebill)</td></tr>
<tr><td>start_ts</td><td>int</td><td>Start timestamp</td></tr>
<tr><td>user_idchange_ts</td><td>int</td><td>PV2 user IDChange(edit) timestamp</td></tr>
<tr><td>tracking_userend_ts</td><td>int</td><td>User ID on partners' siteEnd timestamp</td></tr>
<tr><td>ptnr_idrebill_count</td><td>int</td><td>Partner IDNumber of recurring payments</td></tr>
<tr><td>tracking_taglast_rebill_ts</td><td>int</td><td>Tracking Tag paramLast rebill ts</td></tr>
<tr><td>currencynext_rebill_ts</td><td>stringint</td><td>CurrencyNext rebill ts</td></tr>
<tr><td>hashnext_rebill_amount</td><td>stringint</td><td>HashNext rebill amount</td></tr>
<tr><td>pp_namestep_down</td><td>stringint</td><td>PP NameStep Down (charge amount reductions)</td></tr>
<tr><td>trial_unitorder_id</td><td>stringint</td><td>Trial Unit (day|week|month|year)Order ID</td></tr>
<tr><td>trial_period</td><td>int</td><td>Trial perioddescription</td><td>int</td><td>Order Description</td></tr>
<tr><td>rebill_amount</td><td>int</td><td>Rebill amount (not including next one)</td></tr>
<tr><td>trial_unit</td><td>string</td><td>Trial Unit (day|week|month|year)</td></tr>
<tr><td>rebill_unit</td><td>string</td><td>Rebill Unit (day|week|month|year)</td></tr>
<tr><td>rebill_period</td><td>int</td><td>Rebill period</td></tr>
<tr><td>max_rebill_count</td><td>int</td><td>Max Rebill Count</td></tr>
<tr><td>trial_period</td><td>int</td><td>Trial period</td></tr>
<tr><td>tracking_item</td><td>int</td><td>Tracking item ID</td></tr>
<tr><td>next_rebill_tspp_id</td><td>int</td><td>Next rebill tsPayment Processor ID</td></tr>
<tr><td>last_rebill_ts</td><td>int</td><td>Last rebill tsuser_id</td><td>int</td><td>PV2 user ID</td></tr>
<tr><td>hash</td><td>string</td><td>Hash</td></tr>
<tr><td>first_name</td><td>int</td><td>Customer's First Name</td></tr>
<tr><td>last_name</td><td>int</td><td>Customer's Last Name</td></tr>
<tr><td>ppac_id</td><td>int</td><td>Payment Processor Account ID</td></tr>
<tr><td>email</td><td>int</td><td>Customer's Email Address</td></tr>
<tr><td>ptnr_id</td><td>int</td><td>Partner ID</td></tr>
<tr><td>currency</td><td>string</td><td>Currency</td></tr>
<tr><td>tracking_tag</td><td>int</td><td>Tracking Tag param</td></tr>
<tr><td>ip</td><td>int</td><td>Customer's IP Address</td></tr>
<tr><td>order_type</td><td>int</td><td>Order type. Values: `basic`, `xsale`</td></tr>
<tr><td>tracking_user</td><td>int</td><td>User ID on partners' site</td></tr>
<tr><td>processor</td><td>int</td><td>Payment Processor's abreviation</td></tr>
<tr><td>tran_id*</td><td>int</td><td>Last Transaction's ID</td></tr>
</table>
//* Not present for all payment processors//
= subscription.stopped
Sent in case of stopped subscription (action initiated via api call)
Data array (json encoded)
<table>
<tr>
<th>Param Name</th><th>Type</th><th>Description</th>
</tr>
<tr><td>sub_id</td><td>int</td><td>Subscription ID</td></tr>
<tr><td>item_id</td><td>int</td><td>Item ID</td></tr>
<tr><td>status</td><td>string</td><td>Subscription status (s/b initial on create, rebill after 1st rebill)</td></tr>
<tr><td>start_ts</td><td>int</td><td>Start timestamp</td></tr>
<tr><td>user_idchange_ts</td><td>int</td><td>PV2 user IDChange(edit) timestamp</td></tr>
<tr><td>tracking_userend_ts</td><td>int</td><td>User ID on partners' siteEnd timestamp</td></tr>
<tr><td>ptnr_idrebill_count</td><td>int</td><td>Partner IDNumber of recurring payments</td></tr>
<tr><td>tracking_taglast_rebill_ts</td><td>int</td><td>Tracking Tag paramLast rebill ts</td></tr>
<tr><td>currencynext_rebill_ts</td><td>stringint</td><td>CurrencyNext rebill ts</td></tr>
<tr><td>hashnext_rebill_amount</td><td>stringint</td><td>HashNext rebill amount</td></tr>
<tr><td>pp_namestep_down</td><td>stringint</td><td>PP NameStep Down (charge amount reductions)</td></tr>
<tr><td>trial_unitorder_id</td><td>stringint</td><td>Trial Unit (day|week|month|year)Order ID</td></tr>
<tr><td>trial_period</td><td>int</td><td>Trial perioddescription</td><td>int</td><td>Order Description</td></tr>
<tr><td>rebill_amount</td><td>int</td><td>Rebill amount (not including next one)</td></tr>
<tr><td>trial_unit</td><td>string</td><td>Trial Unit (day|week|month|year)</td></tr>
<tr><td>rebill_unit</td><td>string</td><td>Rebill Unit (day|week|month|year)</td></tr>
<tr><td>rebill_period</td><td>int</td><td>Rebill period</td></tr>
<tr><td>max_rebill_count</td><td>int</td><td>Max Rebill Count</td></tr>
<tr><td>trial_period</td><td>int</td><td>Trial period</td></tr>
<tr><td>tracking_item</td><td>int</td><td>Tracking item ID</td></tr>
<tr><td>next_rebill_tspp_id</td><td>int</td><td>Next rebill tsPayment Processor ID</td></tr>
<tr><td>last_rebill_ts</td><td>int</td><td>Last rebill tsuser_id</td><td>int</td><td>PV2 user ID</td></tr>
<tr><td>hash</td><td>string</td><td>Hash</td></tr>
<tr><td>first_name</td><td>int</td><td>Customer's First Name</td></tr>
<tr><td>last_name</td><td>int</td><td>Customer's Last Name</td></tr>
<tr><td>ppac_id</td><td>int</td><td>Payment Processor Account ID</td></tr>
<tr><td>email</td><td>int</td><td>Customer's Email Address</td></tr>
<tr><td>ptnr_id</td><td>int</td><td>Partner ID</td></tr>
<tr><td>currency</td><td>string</td><td>Currency</td></tr>
<tr><td>tracking_tag</td><td>int</td><td>Tracking Tag param</td></tr>
<tr><td>ip</td><td>int</td><td>Customer's IP Address</td></tr>
<tr><td>order_type</td><td>int</td><td>Order type. Values: `basic`, `xsale`</td></tr>
<tr><td>tracking_user</td><td>int</td><td>User ID on partners' site</td></tr>
<tr><td>processor</td><td>int</td><td>Payment Processor's abreviation</td></tr>
<tr><td>is_cancel</td><td>boolean</td><td>s/b true</td></tr>
<tr><td>cancel_reason</td><td>string</td><td>Optional, not always sent. If it has value 'cancel_reason_rebill_bin_filter' it means that subscription was stopped because BIN used for purchase is not allowed to rebill.</td></tr>
</table>
= subscription.suspended
Sent in case of suspended subscription (usually happens when we can't rebill user after defined number of attempts)
Data array (json encoded)
<table>
<tr>
<th>Param Name</th><th>Type</th><th>Description</th>
</tr>
<tr><td>sub_id</td><td>int</td><td>Subscription ID</td></tr>
<tr><td>item_id</td><td>int</td><td>Item ID</td></tr>
<tr><td>status</td><td>string</td><td>Subscription status (s/b initial on create, rebill after 1st rebill)</td></tr>
<tr><td>start_ts</td><td>int</td><td>Start timestamp</td></tr>
<tr><td>user_idchange_ts</td><td>int</td><td>PV2 user IDChange(edit) timestamp</td></tr>
<tr><td>tracking_userend_ts</td><td>int</td><td>User ID on partners' siteEnd timestamp</td></tr>
<tr><td>ptnr_idrebill_count</td><td>int</td><td>Partner IDNumber of recurring payments</td></tr>
<tr><td>tracking_taglast_rebill_ts</td><td>int</td><td>Tracking Tag paramLast rebill ts</td></tr>
<tr><td>currencynext_rebill_ts</td><td>stringint</td><td>CurrencyNext rebill ts</td></tr>
<tr><td>hashnext_rebill_amount</td><td>stringint</td><td>HashNext rebill amount</td></tr>
<tr><td>pp_namestep_down</td><td>stringint</td><td>PP NameStep Down (charge amount reductions)</td></tr>
<tr><td>trial_unitorder_id</td><td>stringint</td><td>Trial Unit (day|week|month|year)Order ID</td></tr>
<tr><td>trial_period</td><td>int</td><td>Trial perioddescription</td><td>int</td><td>Order Description</td></tr>
<tr><td>rebill_amount</td><td>int</td><td>Rebill amount (not including next one)</td></tr>
<tr><td>trial_unit</td><td>string</td><td>Trial Unit (day|week|month|year)</td></tr>
<tr><td>rebill_unit</td><td>string</td><td>Rebill Unit (day|week|month|year)</td></tr>
<tr><td>rebill_period</td><td>int</td><td>Rebill period</td></tr>
<tr><td>max_rebill_count</td><td>int</td><td>Max Rebill Count</td></tr>
<tr><td>trial_period</td><td>int</td><td>Trial period</td></tr>
<tr><td>tracking_item</td><td>int</td><td>Tracking item ID</td></tr>
<tr><td>next_rebill_tspp_id</td><td>int</td><td>Next rebill tsPayment Processor ID</td></tr>
<tr><td>last_rebill_ts</td><td>int</td><td>Last rebill tsuser_id</td><td>int</td><td>PV2 user ID</td></tr>
<tr><td>hash</td><td>string</td><td>Hash</td></tr>
<tr><td>first_name</td><td>int</td><td>Customer's First Name</td></tr>
<tr><td>last_name</td><td>int</td><td>Customer's Last Name</td></tr>
<tr><td>ppac_id</td><td>int</td><td>Payment Processor Account ID</td></tr>
<tr><td>email</td><td>int</td><td>Customer's Email Address</td></tr>
<tr><td>ptnr_id</td><td>int</td><td>Partner ID</td></tr>
<tr><td>currency</td><td>string</td><td>Currency</td></tr>
<tr><td>tracking_tag</td><td>int</td><td>Tracking Tag param</td></tr>
<tr><td>ip</td><td>int</td><td>Customer's IP Address</td></tr>
<tr><td>order_type</td><td>int</td><td>Order type. Values: `basic`, `xsale`</td></tr>
<tr><td>tracking_user</td><td>int</td><td>User ID on partners' site</td></tr>
<tr><td>processor</td><td>int</td><td>Payment Processor's abreviation</td></tr>
</table>
= subscription.rebill
Sent after successfully made rebill. It will be sent right after transaction.success
Data array (json encoded)
<table>
<tr>
<th>Param Name</th><th>Type</th><th>Description</th>
</tr>
<tr><td>sub_id</td><td>int</td><td>Subscription ID</td></tr>
<tr><td>item_id</td><td>int</td><td>Item ID</td></tr>
<tr><td>status</td><td>string</td><td>Subscription status (s/b initial on create, rebill after 1st rebill)</td></tr>
<tr><td>start_ts</td><td>int</td><td>Start timestamp</td></tr>
<tr><td>user_idchange_ts</td><td>int</td><td>PV2 user IDChange(edit) timestamp</td></tr>
<tr><td>tracking_userend_ts</td><td>int</td><td>User ID on partners' siteEnd timestamp</td></tr>
<tr><td>ptnr_idrebill_count</td><td>int</td><td>Partner IDNumber of recurring payments</td></tr>
<tr><td>tracking_taglast_rebill_ts</td><td>int</td><td>Tracking Tag paramLast rebill ts</td></tr>
<tr><td>currencynext_rebill_ts</td><td>stringint</td><td>CurrencyNext rebill ts</td></tr>
<tr><td>hashnext_rebill_amount</td><td>stringint</td><td>HashNext rebill amount</td></tr>
<tr><td>pp_namestep_down</td><td>stringint</td><td>PP NameStep Down (charge amount reductions)</td></tr>
<tr><td>trial_unitorder_id</td><td>stringint</td><td>Trial Unit (day|week|month|year)Order ID</td></tr>
<tr><td>trial_period</td><td>int</td><td>Trial perioddescription</td><td>int</td><td>Order Description</td></tr>
<tr><td>rebill_amount</td><td>int</td><td>Rebill amount (not including next one)</td></tr>
<tr><td>trial_unit</td><td>string</td><td>Trial Unit (day|week|month|year)</td></tr>
<tr><td>rebill_unit</td><td>string</td><td>Rebill Unit (day|week|month|year)</td></tr>
<tr><td>rebill_period</td><td>int</td><td>Rebill period</td></tr>
<tr><td>max_rebill_count</td><td>int</td><td>Max Rebill Count</td></tr>
<tr><td>trial_period</td><td>int</td><td>Trial period</td></tr>
<tr><td>tracking_item</td><td>int</td><td>Tracking item ID</td></tr>
<tr><td>next_rebill_tspp_id</td><td>int</td><td>Next rebill tsPayment Processor ID</td></tr>
<tr><td>last_rebill_ts</td><td>int</td><td>Last rebill tsuser_id</td><td>int</td><td>PV2 user ID</td></tr>
<tr><td>hash</td><td>string</td><td>Hash</td></tr>
<tr><td>first_name</td><td>int</td><td>Customer's First Name</td></tr>
<tr><td>last_name</td><td>int</td><td>Customer's Last Name</td></tr>
<tr><td>ppac_id</td><td>int</td><td>Payment Processor Account ID</td></tr>
<tr><td>email</td><td>int</td><td>Customer's Email Address</td></tr>
<tr><td>ptnr_id</td><td>int</td><td>Partner ID</td></tr>
<tr><td>currency</td><td>string</td><td>Currency</td></tr>
<tr><td>tracking_tag</td><td>int</td><td>Tracking Tag param</td></tr>
<tr><td>ip</td><td>int</td><td>Customer's IP Address</td></tr>
<tr><td>order_type</td><td>int</td><td>Order type. Values: `basic`, `xsale`</td></tr>
<tr><td>tracking_user</td><td>int</td><td>User ID on partners' site</td></tr>
<tr><td>processor</td><td>int</td><td>Payment Processor's abreviation</td></tr>
<tr><td>tran_id*</td><td>int</td><td>Last Transaction's ID</td></tr>
</table>
//* Not present for all payment processors//
= subscription.completed
Sent after completed subscription (happens only on subs with limited number of rebills).
Data array (json encoded)
<table>
<tr>
<th>Param Name</th><th>Type</th><th>Description</th>
</tr>
<tr><td>sub_id</td><td>int</td><td>Subscription ID</td></tr>
<tr><td>item_id</td><td>int</td><td>Item ID</td></tr>
<tr><td>status</td><td>string</td><td>Subscription status (s/b initial on create, rebill after 1st rebill)</td></tr>
<tr><td>start_ts</td><td>int</td><td>Start timestamp</td></tr>
<tr><td>user_idchange_ts</td><td>int</td><td>PV2 user IDChange(edit) timestamp</td></tr>
<tr><td>tracking_userend_ts</td><td>int</td><td>User ID on partners' siteEnd timestamp</td></tr>
<tr><td>ptnr_idrebill_count</td><td>int</td><td>Partner IDNumber of recurring payments</td></tr>
<tr><td>tracking_taglast_rebill_ts</td><td>int</td><td>Tracking Tag paramLast rebill ts</td></tr>
<tr><td>currencynext_rebill_ts</td><td>stringint</td><td>CurrencyNext rebill ts</td></tr>
<tr><td>hashnext_rebill_amount</td><td>stringint</td><td>HashNext rebill amount</td></tr>
<tr><td>pp_namestep_down</td><td>stringint</td><td>PP NameStep Down (charge amount reductions)</td></tr>
<tr><td>trial_unitorder_id</td><td>stringint</td><td>Trial Unit (day|week|month|year)Order ID</td></tr>
<tr><td>trial_period</td><td>int</td><td>Trial perioddescription</td><td>int</td><td>Order Description</td></tr>
<tr><td>rebill_amount</td><td>int</td><td>Rebill amount (not including next one)</td></tr>
<tr><td>trial_unit</td><td>string</td><td>Trial Unit (day|week|month|year)</td></tr>
<tr><td>rebill_unit</td><td>string</td><td>Rebill Unit (day|week|month|year)</td></tr>
<tr><td>rebill_period</td><td>int</td><td>Rebill period</td></tr>
<tr><td>max_rebill_count</td><td>int</td><td>Max Rebill Count</td></tr>
<tr><td>trial_period</td><td>int</td><td>Trial period</td></tr>
<tr><td>tracking_item</td><td>int</td><td>Tracking item ID</td></tr>
<tr><td>next_rebill_tspp_id</td><td>int</td><td>Next rebill tsPayment Processor ID</td></tr>
<tr><td>last_rebill_ts</td><td>int</td><td>Last rebill tsuser_id</td><td>int</td><td>PV2 user ID</td></tr>
<tr><td>hash</td><td>string</td><td>Hash</td></tr>
<tr><td>first_name</td><td>int</td><td>Customer's First Name</td></tr>
<tr><td>last_name</td><td>int</td><td>Customer's Last Name</td></tr>
<tr><td>ppac_id</td><td>int</td><td>Payment Processor Account ID</td></tr>
<tr><td>email</td><td>int</td><td>Customer's Email Address</td></tr>
<tr><td>ptnr_id</td><td>int</td><td>Partner ID</td></tr>
<tr><td>currency</td><td>string</td><td>Currency</td></tr>
<tr><td>tracking_tag</td><td>int</td><td>Tracking Tag param</td></tr>
<tr><td>ip</td><td>int</td><td>Customer's IP Address</td></tr>
<tr><td>order_type</td><td>int</td><td>Order type. Values: `basic`, `xsale`</td></tr>
<tr><td>tracking_user</td><td>int</td><td>User ID on partners' site</td></tr>
<tr><td>processor</td><td>int</td><td>Payment Processor's abreviation</td></tr>
</table>
= subscription.change
Sent in when subscription is changed (action initiated via `subscription.change` api call)
Data array (json encoded)
<table>
<tr>
<th>Param Name</th><th>Type</th><th>Description</th>
</tr>
<tr><td>sub_id</td><td>int</td><td>Subscription ID</td></tr>
<tr><td>item_id</td><td>int</td><td>Item ID</td></tr>
<tr><td>status</td><td>string</td><td>Subscription status (s/b initial on create, rebill after 1st rebill)</td></tr>
<tr><td>start_ts</td><td>int</td><td>Start timestamp</td></tr>
<tr><td>user_idchange_ts</td><td>int</td><td>PV2 user IDChange(edit) timestamp</td></tr>
<tr><td>tracking_userend_ts</td><td>int</td><td>User ID on partners' sitent</td></tr>
<tr><td>ptnr_id</td><td>int</td><td>Partner IDEnd timestamp</td></tr>
<tr><td>tracking_tagrebill_count</td><td>int</td><td>Tracking Tag param</td></tr>
<tr><td>currency</td><td>stNumber of recurring</td><td>Currency payments</td></tr>
<tr><td>hash</td><td>string</td><td>Hash</td></tr>
<tr><td>pp_name</td><td>string</td><td>PP Name</td></tr>
<tr><td>trial_unit</td><td>string</td><td>Trial Unit (day|week|month|year)</td></tr>
<tr><td>trial_period</td><td>int</td><td>Trial period</td></tr>
<tr><td>rebill_unit</td><td>string</td><td>Rebill Unit (day|week|month|year)</td></tr>
<tr><td>rebill_period</td><td>int</td><td>Rebill period</td></tr>
<tr><td>max_rebill_count</td><td>int</td><td>Max Rebill Count</td></tr>
<tr><td>tracking_item</td><td>int</td><td>Tracking item IDlast_rebill_ts</td><td>int</td><td>Last rebill ts</td></tr>
<tr><td>next_rebill_ts</td><td>int</td><td>Next rebill ts</td></tr>
<tr><td>lasnext_rebill_tsamount</td><td>int</td><td>LasNext rebill tsamount</td></tr>
</table>
= subscriptr><td>step_down</td><td>int</td><td>Step Down (charge amount reductions.prerebill)</td></tr>
(WIP) Sent from cron job that runs at 1h frequency.<tr><td>order_id</td><td>int</td><td>Order ID</td></tr>
Data consists of sub<tr><td>descriptions that are due to rebill in next X days, where X is configurable from cron manager.</td><td>int</td><td>Order Description</td></tr>
(one value of X per one cron job instance)
Data array (json encoded)<tr><td>rebill_amount</td><td>int</td><td>Rebill amount (not including next one)</td></tr>
<tabletr><td>trial_unit</td><td>string</td><td>Trial Unit (day|week|month|year)</td></tr>
<tr><td>rebill_unit</td><td>string</td><td>Rebill Unit (day|week|month|year)</td></tr>
<th>Param Name</th><th>Type</th><th>Description</th<tr><td>rebill_period</td><td>int</td><td>Rebill period</td></tr>
<tr><td>max_rebill_count</td><td>int</td><td>Max Rebill Count</td></tr>
<tr><td>intervaltrial_period</td><td>stringint</td><td>When from now should rebill happen ('2 day', '3 day', 'X day')Trial period</td></tr>
<tr><td>subscriptionstracking_item</td><td>arrayint</td><td>Array of data related to subscriptions rebills (see below)Tracking item ID</td></tr>
</table>
Subscriptions array (json encoded)tr><td>pp_id</td><td>int</td><td>Payment Processor ID</td></tr>
<tabletr><td>user_id</td><td>int</td><td>PV2 user ID</td></tr>
<tr><td>hash</td><td>string</td><td>Hash</td></tr>
<th>Param N<tr><td>first_name</th><th>Type</th><th>Description</thd><td>int</td><td>Customer's First Name</td></tr>
<tr><td>last_name</td><td>int</td><td>Customer's Last Name</td></tr>
<tr><td>subppac_id</td><td>int</td><td>SubscriptionPayment Processor Account ID</td></tr>
<tr><td>next_rebill_tsemail</td><td>int</td><td>Next rebill timestampCustomer's Email Address</td></tr>
<tr><td>ptnr_id</td><td>int</td><td>Partner ID</td></tr>
<tr><td>tracking_user</td><td>int</td><td>User ID on partners' site</td></tr>
<tr><td>tracking_tag</td><td>int</td><td>Tracking Tag param</td></tr>
<tr><td>bin</td><td>string</td><td>BIN of card for this susbcription</td></tr>
<tr><td>ccnum_last4</td><td>string</td><td>Last 4 digits of card for this susbcription</td></tr>
<tr><td>currency</td><td>string</td><td>Currency</td></tr>
<tr><td>order_typetracking_tag</td><td>stringint</td><td>Order type ('basic' | 'xsale')</td></tr>
<tr><td>item_id</td><td>int</td><td>Item IDTracking Tag param</td></tr>
<tr><td>cc_typeip</td><td>stringint</td><td>Card type ('visa' ...)ustomer's IP Address</td></tr>
<tr><td>pp_namorder_type</td><td>stringint</td><td>PP NameOrder type. Values: `basic`, `xsale`</td></tr>
<tr><td>bin_high_risktracking_user</td><td>int</td><td>Is BINUser ID on High Risk List (1|0)partners' site</td></tr>
<tr><td>bin_blocked_for_rebillprocessor</td><td>int</td><td>Is BIN blocked for rebill (1|0)Payment Processor's abreviation</td></tr>
</table>