Order Process

Most of the order process is done outside the scope of billwerk. The app provider additionally processes an order on billwerk side by providing order information (receipt) as a replacement for the cart. The billwerk order process follows the same steps as usual (Create & Commit). billwerk will verify the passed receipt against the IAP provider. If the receipt is valid, billwerk will create a customer and a contract as usual.

🚧

Warning

Keep subscriptions of the different IAP platforms and billwerk in separate contracts at all time. Once a billwerk contract holds subscriptions of a specific platform do not up/-downgrade to subscriptions of another IAP platform or non-IAP billwerk subscriptions!

Keeping in mind that billwerk takes the role of an observer for IAP the order process can be visualized as follows:

Checking IAP subscriptions

billwerk offers an endpoint to check which subscriptions a receipt contains and which of them are already in billwerk. To see if a subscription already has a contract in billwerk, check if the Contract field exists within the returned subscription. If not, you probably want to create an order to add it. This approach can be used to handle receipt restorations. For Apple, this endpoint requires the receipt, and it can return multiple subscriptions. For other providers, it requires the same data as creating an order does, and it returns only one subscription.

POST /api/v1/ExternalSubscriptions/check

Apple

{
    "Type":"AppleIap",
    "AppleIapReceipt": "..."
}

Google

{
    "Type":"GoogleIap",
    "GoogleIapPackageName": "...",
    "GoogleIapSubscriptionId": "...",
    "GoogleIapToken": "..."
}

Amazon

{
    "Type":"AmazonIap",
    "AmazonIapReceiptId": "...",
    "AmazonIapUserId": "..."
}

Response

{
    "Subscriptions":[
        {
            "Id": "<Existing ExternalSubscriptionId>",
            "Contract": { // present if we have a contract for that subscription in billwerk
                "Id": "<ContractId>",
                "CustomerId": "<CustomerId>"
            }
        },{
            "Id": "<New ExternalSubscriptionId>"
            // Contract is missing here, so it's not in billwerk yet
        }
    ]
}

IAP Orders

In contrast to non IAP orders, where the Cart property is used, an IAP order accepts an ExternalSubscriptionId at the top level, which can be obtained from the Check REST API endpoint. This approach works for all providers. It is mandatory for Apple. For Amazon and Google both the ExternalSubscriptionId approach and using ExternalCart approach will work.

Apple, Google, Amazon Request

{
    "ExternalSubscriptionId": "<SubscriptionId>",
    "CustomerId":"599d51f823a1610b27a76252",
    ...
}

Google Example Response

{
    "Customer":{
        "FirstName":"Marcellus",
        "LastName":"Wallace"
    },
    "ExternalCart":{
        "Type":"GoogleIap",
        "GoogleIapPackageName":"...",
        "GoogleIapSubscriptionId":"...",
        "GoogleIapToken":"..."
    },
    ...
}

Amazon Example Response

{
    "Customer":{
        "FirstName":"Marcellus",
        "LastName":"Wallace"
    },
    "ExternalCart":{
        "Type":"AmazonIap",
        "AmazonIapReceiptId":"...",
        "AmazonIapUserId":"..."
    },
    ...
}