BillRun billing can support external sources, such CRM or ERP, for customers and subscriptions datastore instead of a local database that stores this information. The other system doesn't need provisioning customers and subscribers to the billing, but just exposing the API listed in this document (GSD, GAD and Billable).
The extenral API can support secure API with OAuth2.
When BillRun is in “external” subscribers mode, in config:
subscribers.subscriber.type = “external” ,
subscribers.subscriber.external_url = "http://<CRM ADDRESS>/<GSD_URL>"
Each CDR line creator needs to be identified, BillRun will send an aggregated request to the CRM, with the CDRs identification data.
API Description: depending on the params sent in the queries, expects to get back an array of matching results.
HTTP Method: POST
Format: JSON
Structure:
Format : JSON
Structure:
http://host/path_to_api?query=[{"id":"0987654321gfedcba","time":"2019-10-20 08:23:38","params":[{"key": "field1", "operator": "equal", "value": "555555"},{,"key": field2, "operator": "in", "value": ["55555", "66666", "77777"]}], {,"id":"abcdefg1234567890","time":"2019-10-20 08:23:38","params":[{"key": "field1", "operator": "equal", "value": 123123}, {"key": field2, "operator": "in", "value": ["123456", "87654532"]}],limit:1,time:"2019-10-20 08:23:38"}]&limit=2&time=2019-10-20 08:23:38
[ { “id": “0987654321gfedcba", “from": “2019-01-01 09:00:00", "to":"2019-10-01 09:00:00", "aid":132, "sid":3, "plan":"SIMPLE_PLAN", "services": [ { “name":"SIMPLE_SERVICE", "from":"2019-01-01 10:00:00", "to":"2019-09-01 10:00:00", "service_id": 1541524671067, "creation_time":"2019-09-01 10:00:00" } ], "play":"mobile", "firstname":"a", "lastname":"b", "address":"c", "country":"Denmark", "plan_activation":"2019-09-01 10:00:00", "plan_deactivation":"2019-10-01 10:00:00", "activation_date":"2019-09-01 10:00:00", "deactivation_date":"2119-09-01 10:00:00", "former_plan":"OLDER_PLAN" } ]
When billrun accounts mode is “external”, in config:
subscribers.account.type = “external” ,
subscribers.account.external_url = "http://CRM ADDRESS/GAD_URL"
BillRun will make this API request in order to retrieve account data from the CRM in the following flows:
HTTP Method: POST
Format: JSON
Structure:
Format : JSON
Structure:
Account revision |
|||
Parameter |
Type |
Description |
Inner Structure |
id | String | The id representing the query that produced this result | |
aid | int | account ID |
- |
from | string (Y-m-d H:i:s) | revision start_date |
- |
to | string (Y-m-d H:i:s) | Revision end_date |
- |
string |
- |
||
invoice_shipping_method | string |
One of [email, post, website] |
- |
invoice_detailed | boolean |
- |
|
address | string | account address |
- |
<custom_field> | string | every custom field that is mandatory in the system |
- |
tenant_return_url | string |
- |
|
creation_time | String (Y-m-d H:i:s) | account creation date |
- |
http://host/path_to_api?query=[{“params”:[{‘key’: ‘field1’, ‘operator’: ‘equal’, ‘value’: ‘555555’}, {‘key’: field2, ‘operator’: 'in', ‘value’: [‘55555’, ’66666’, ‘77777’]}], “time”:”2019-10-20 08:23:38”,”id”:”7b7a8b8a9b9a6b6a5b5a”,”limit”:”1”}]&time=2019-10-20 08:23:38&limit=1
[ { "id": "7b7a8b8a9b9a6b6a5b5a", "aid":132, "from": "2019-01-01 09:00:00", "to":"2019-10-01 09:00:00", "email":"a@gmail.com", "invoice_shipping_method":"post", "invoice_detailed":false, "address":"xxxxxxxx", "custom_field1":"123", "tenant_return_url":"http://abs.com", "payment_gateway": { "active": { "name":"xxx", "card_token":"1234", "card_expiration":"2019-01-01 09:00:00", "personal_id":"xxxxxx", "transaction_exhausted":false, "generate_token_time":"2019-01-01 09:00:00", "auth_number":"xxxxx", "four_digits":"1234" } }, "creation_time":"2019-09-01 10:00:00" } ]
Description: When billrun mode is “external”, in config:
subscribers.account.type = “external” ,
subscribers.subscriber.type = "external”
subscribers.billable.url = "http[s]://[CRM_HOST]/[CRM_URL]"
Before the billing cycle is executed, it requests the CRM for all the active accounts in the CRM that should be billed. Then it uses the returned data to generate the account invoice for the billrun (The pagination sort should be by the account ID). It is recommended to return revisions from a few months back, even if none are active during the requested billing cycle. This will allow charging of deactivated subscribers in case they have same chargeable records in the requested cycle.
The system request will contain the <start_date> and <end_date> of the required cycle, pagination params i.e <page> & <size>, and an optional <account ids> array of integers which represents specific account ids that should be returned in the response.
Note that for pagination purposes, you are required to prepare results accordingly, (i.e. two responses should not have overlapping data). The system will stop sending requests once it receives empty responses, hence non-full/ empty responses should happen only when there are no more results to return.
A response should include all relevant revision data for any active subscriber/account during the given dates. The following describes the necessary data:
Subscriber Revision |
|||
Parameter |
Type |
Description |
Inner Structure |
type | string | The revision type value should always be ‘subscriber’ for subscriber revisions |
“subscriber” |
sid | int | subscriber ID |
- |
aid | int | account ID |
- |
from | string (Y-m-d H:i:s) | Revision start_date |
- |
to | string (Y-m-d H:i:s) | Revision end_date |
- |
plan | string | Subscriber’s plan key |
- |
services | array | all subscriber’s services for this revision |
- name (string) - from (Y-m-d H:i:s) - to (Y-m-d H:i:s) - service_id (int) - creation_time (Y-m-d H:i:s) - quantity (int optional) |
play | string | Subscriber type |
- |
firstname | string | subscriber first name |
- |
lastname | string | subscriber last name |
- |
address | string | subscriber address |
- |
<custom_field> | string | Every custom field that is mandatory in the system |
- |
former_plan | string | the last plan the subscriber had, if any |
- |
discounts | array | all subscriber-level discounts for this revision. If there are multiple revisions for the subscriber, only the discounts from the last revision of the cycle are taken into account. |
see discounts API |
plan_activation | String (Y-m-d H:i:s) | subscriber’s plan activation start date |
- |
plan_deactivation | String (Y-m-d H:i:s) | subscriber’s plan activation end date |
- |
activation_date | String (Y-m-d H:i:s) | when did the subscriber start to exist |
- |
deactivation_date | String (Y-m-d H:i:s) | when will the subscriber no longer exist |
- |
creation_time | String (Y-m-d H:i:s) | subscriber’s creation date |
- |
overrides - | array of objects, optional | an array of overrides expression objects used to overrides plans and services values such as price or rates associations |
Account revision |
|||
Parameter |
Type |
Description |
Inner Structure |
type | string | The revision type value should always be account for account revisions |
“account” |
aid | int | account ID |
- |
from | string (Y-m-d H:i:s) | revision start_date |
- |
to | string (Y-m-d H:i:s) | Revision end_date |
- |
string |
- |
||
invoice_shipping_method | string |
One of [email, mail, website] |
- |
invoice_detailed | boolean |
- |
|
address | string | account address |
- |
<custom_field> | string | every custom field that is mandatory in the system |
- |
creation_time | String (Y-m-d H:i:s) | account creation date |
- |
activation_date | String (Y-m-d H:i:s) | Account activation date |
- |
deactivation_date | String (Y-m-d H:i:s) | Account deactivation date |
- |
services | Array | all customer’s services for this revision |
- name (string) - from (Y-m-d H:i:s) - to (Y-m-d H:i:s) - service_id (int) - creation_time (Y-m-d H:i:s) - quantity (int optional) |
overrides - | array of objects, optional | an array of overrides expression objects used to overrides plans and services values such as price or rates associations |
In addition, each “billable” request should also return extra “options” parameters to the billing cycle, if exists. For example you can send under “options” -> “merge_credit_installments” array of account IDs and their subscribers IDs - to merge their future credit installments, e.g in order to merge the credit installment of subscriber id (SID) 6, of account ID 10, and also, SIDs 8,9 of account ID 11, the API response will be:
{
status: [0,1],
data: [
{<account revision>}, ---> first object is account revision
{<subscriber revision>},
…,
{<subscriber revision>}]
options:[
“merge_credit_installments” : [
10 : [6],
11 : [8,9]
]
]
}
HTTP Method: POST
Outgoing Request parameters:
Parameter |
Type |
Description |
start_date | string | Cycle start date |
end_date | string | Cycle end date |
page | int | the page offset ( offset * size ) of the accounts & subscribers revisions to return |
size | int | amount of the expected accounts in results for the request |
aids | string | Optional. if passed, the request is only for these comma-separated account ids. |
Format : JSON
Structure:
{
status: [0,1],
data: [
{<account revision>}, ---> first object is account revision
{<subscriber revision>},
…,
{<subscriber revision>}]
options:[ ]
}
parameter | type | description | structure |
status | boolean | success / failure | |
data | array of objects | revisions of all the subscribers & accounts that were active during the billing cycle |
http://host/path_to_billable_api?start_date=2019-10-01&end_date=2019-10-31&page=0&size=500&aids=134,135,240
{ "status" : 1, "data" : [ { "aid": 314155, "sid": 161803, "plan": "BIG_PLAN", "services": [ ], "firstname": "example", "lastname": "revision", "address": "some place in some city", "phone_number": "0512345678", "ndcsn": "512667508", "imsi": [ "425086000401337", "425019301401337" ], "type": "subscriber", "plan_activation": "2019-11-21T11:17:37", "to": "2168-09-16T09:07:50", "deactivation_date": "2168-09-16T09:07:50", "from": "2019-11-21T11:17:38", "creation_time": "2019-09-16T08:07:50", "activation_date": "2019-09-16T08:07:50", "plan_deactivation": "2168-09-16T09:07:50", "overrides" : [ { "type" : "service", "key" : "SERVICE1", "value" : { "price" : [ { "price" : 0, "from" : 0, "to" : "UNLIMITED" } ] } } ] } ], "options":[] }
You can use overrides to override pricing and other element of the plan or service on a specific subscriber or account.
The override object is as follows:
Override object | ||
---|---|---|
type | string | The entity type to override (plan or service) |
key | string | The entity key to override (plan key or service key) |
value | object | JSON object of the fields and their override values. For instance, the plan / service price can be overridden for a limited/unlimited number of billing cycles, using the “from” / “to” fields (See example above) |
condition | object | a standard condition object to filter the entities |
id | string | optional - If the override type is ‘service’ then this field will represent the service_id in the services array to override. |
A discount object can be added using the same structure of the discounts API.
Another option available only for subscribers is to add a discount with the same key as a discount in the general discounts screen. With that method the linked general discount will automatically apply to the subscriber even if the discount's conditions do not normally apply to the subscriber.
It is also possible to add other discount fields that will override the general discount fields for that subscriber such as subject (discount amount) and other fields in the discount.
For example the if the following general discount only applies to subscriber from specific countries:
Adding the following object to the GBA of a subscriber will apply the discount on that subscriber regardless of the country of the subscriber:
"discounts" : [
{
"key" : DISCOUNT_123,
}
]
Furthermore, adding the following object to the GBA of a subscriber will apply the discount on that subscriber regardless of the country of the subscriber and also change the amount of the discount to 90:
"discounts" : [
{
"key" : "DISCOUNT_123",
"subject" : {
"plan" : {
"PLAN_123" : {
"value" : 90
}
}
}
}
]
Description: When a defined threshold is met the system will send notification with details.
Structure as follows:
HTTP Method: GET
http://host?event_code=TOTAL_COST&event_type=balance&before=0&after=5&based_on=monetary&
stamp=90d9b683d0f3912a41166e5aa8ac27bc&start_notify_time=1513604493&creation_time=1513603493&
extra_params={“aid":2, "sid":7, “row":{"usagev":60,"urt":1513604493}}&
conditions=[{“path":"balance.cost","unit":"","usaget":"","Type":"reached_constant_recurring"},"value":10]
Structure:
Format:JSON
{“success”: true}