INTRODUCTION

Many common actions require modifying resources in a particular way, obeying a number of constraints. We've collected a few use cases for common scenarios here.


CONTRACTS

Adding contract for new customer

For simple signup/subscription implementation we recommend using SubscriptionJS rather than API, unless you have strong reasons.

Sample Request
POST /Orders
{
  "TriggerInterimBilling": false,
  "Cart": {
    "PlanVariantId": "5dd15e3f9cc9ba309478eedf",
    "InheritStartDate": false,
    "ComponentSubscriptions": [
      {
        "ComponentId": "5dd15e3f9cc9ba309478eedd",
        "Quantity": 2.0
      }
    ]
  },
  "Customer": {
    "CompanyName": "ACME Inc.",
    "FirstName": "John",
    "LastName": "Doe",
    "VatId": "DE424324234",
    "EmailAddress": "john.doe@example.com",
    "Address": {
      "AddressLine1": "c/o Coworking Ltd.",
      "Street": "Zschopauer Straße",
      "HouseNumber": "42",
      "PostalCode": "10123",
      "City": "Berlin",
      "Country": "DE"
    },
    "Hidden": false
  },
  "PreviewAfterTrial": false
}

Remove ComponentSubscriptions or pass empty array if no components are subscribed.

Sample Response
{
  "Id": "5dd15e3f9cc9ba309478eeee",
  "AllowWithoutPaymentData": true,
  "ComponentSubscriptions": [
    {
      "ComponentType": "QuantityBased",
      "PreventModification": false,
      "VatPercentage": 19.0,
      "TotalNet": 2.0,
      "TotalVat": 0.38,
      "IsQuantityBased": false,
      "ComponentId": "5dd15e3f9cc9ba309478eedd",
      "Quantity": 2.0
    }
  ],
  "Total": 7.0,
  "TotalVat": 1.33,
  "TotalGross": 0.0,
  "NextTotalGross": 0.0,
  "IsTrial": false,
  "TrialEndPolicy": "NoTrial",
  "Status": "InProgress",
  "OrderType": "Signup",
  "TriggerInterimBilling": false,
  "CustomerId": "5dd15e3f9cc9ba309478eeef",
  "ContractId": "5dd15e3f9cc9ba309478eec4",
  "PreviewAfterTrial": false
}

Adding contract to existing customer

To create a second contract for a customer requires a somewhat different process than creating a new customer altogether, because we have no way of identifying, authenticating or authorizing your customers. Hence, to create a second contract for an existing customer, the request must go through your server's backend to the REST API. However, that separation makes sense because the workflow is quite different from an end-user perspective, usually. Re-entering a lot of information seems useless, and the order process usually doesn't involve the public web site's checkout process.

Create order

Sample Request
POST /Orders
{
  "TriggerInterimBilling": false,
  "CustomerId": "5dd15e3f9cc9ba309478eeef",
  "Cart": {
    "PlanVariantId": "5dd15e3f9cc9ba309478eedf",
    "InheritStartDate": false,
    "ComponentSubscriptions": [
      {
        "ComponentId": "5dd15e3f9cc9ba309478eedd",
        "Quantity": 2.0
      }
    ]
  },
  "PreviewAfterTrial": false
}
Sample Response
{
  "Id": "5dd15e3f9cc9ba309478eef0",
  "AllowWithoutPaymentData": true,
  "ComponentSubscriptions": [
    {
      "ComponentType": "QuantityBased",
      "PreventModification": false,
      "VatPercentage": 19.0,
      "TotalNet": 2.0,
      "TotalVat": 0.38,
      "IsQuantityBased": false,
      "ComponentId": "5dd15e3f9cc9ba309478eedd",
      "Quantity": 2.0
    }
  ],
  "Total": 7.0,
  "TotalVat": 1.33,
  "TotalGross": 0.0,
  "NextTotalGross": 0.0,
  "IsTrial": false,
  "TrialEndPolicy": "NoTrial",
  "Status": "InProgress",
  "OrderType": "Signup",
  "TriggerInterimBilling": false,
  "CustomerId": "5dd15e3f9cc9ba309478eef1",
  "ContractId": "5dd15e3f9cc9ba309478eec4",
  "PreviewAfterTrial": false
}

Commit the order through a payment

The details depend on your payment requirements. If the customer only pays on account or you let him signup without payment data you can also use an API call. In the more common use case where you need to (or at least want to have the option to) collect payment data again, we're facing the interactive payment process implemented in SubscriptionJS again.

SubscriptionJS offers a method paySignupInteractive(subscriptionJSPayment, secretPaymentData, order, success, error) that you can use to perform the interactive payment of an order. This method is internally called by SubscriptionJS's subscribe(), too. However, subscribe() also creates the order via JS. In other words, creating orders is one of the few processes that can be performed both via JS and via the REST API.


Adding future contract without invoicing

By default billwerk invoices contract instantly as they are usually prepaid. To work around this behaviour you need a planvariant which costs nothing. If you now subscribe your customers to this planvariant there will be no costs for now. After this step you have to create and commit an upgrade order with the start date in the future. If this date is reached the system will bill.

Sample Request - Signup Order
POST /Orders
{
    "Cart":{
        "PlanVariantId":"5cb72076443e5521a8bexxxx"
    },
    "CustomerId":"5cd183b8443e551e4446xxxx"
}
Sample Response - Signup Order
{
    ...
    "Currency":"EUR",
    "Total":0,
    "TotalVat":0,
    "TotalGross":0,
    "NextTotalGross":0,
    ...
}
Sample Request - Upgrade Order
{
    "ContractId":"5ced07d14de0841b78b0fb0f",
    "Cart":{
        "PlanId":"5c8ba204443e55181c34c62f",
        "PlanVariantId":"5c8ba204443e55181c34c633"
    },
    "ChangeDate":"2019-06-01T00:00:00.000Z"
}

Up-/Downgrading to a plan

Sample Request
POST /Orders
{
  "TriggerInterimBilling": false,
  "ContractId": "5dd15e3f9cc9ba309478eec4",
  "Cart": {
    "PlanVariantId": "5dd15e3f9cc9ba309478eee0",
    "InheritStartDate": false,
    "ComponentSubscriptions": [
      {
        "ComponentId": "5dd15e3f9cc9ba309478eedd",
        "Quantity": 2.0
      }
    ],
    "MeteredUsages": [
      {
        "ComponentId": "5dd15e3f9cc9ba309478eee3",
        "Quantity": 3.0,
        "Memo": "Memo text",
        "Key": "Some unique external key 12345",
        "DueDate": "2019-11-16T14:50:39.7497178Z"
      }
    ],
    "EndComponentSubscriptions": [
      "5dd15e3f9cc9ba309478eee1",
      "5dd15e3f9cc9ba309478eee2"
    ]
  },
  "PreviewAfterTrial": false
}

By default up-/downgrade orders are processed instantly after commit with POST /Orders/:OrderId/commit.

An up-/downgrade of a plan will change all future billing times. Billing periods will be calculated based on the up-/downgrade time.

With an up-/downgrade you can also add/remove component subscriptions and pass metered usage. Omit ComponentSubscriptions, EndComponentSubscriptions, MeteredUsages or pass empty array if not used.

Sample Response
{
  "Id": "5dd15e3f9cc9ba309478eef0",
  "AllowWithoutPaymentData": true,
  "ComponentSubscriptions": [
    {
      "ComponentType": "QuantityBased",
      "PreventModification": false,
      "VatPercentage": 19.0,
      "TotalNet": 2.0,
      "TotalVat": 0.38,
      "IsQuantityBased": false,
      "ComponentId": "5dd15e3f9cc9ba309478eedd",
      "Quantity": 2.0
    }
  ],
  "Total": 7.0,
  "TotalVat": 1.33,
  "TotalGross": 0.0,
  "NextTotalGross": 0.0,
  "IsTrial": false,
  "TrialEndPolicy": "NoTrial",
  "Status": "InProgress",
  "OrderType": "Signup",
  "TriggerInterimBilling": false,
  "CustomerId": "5dd15e3f9cc9ba309478eef1",
  "ContractId": "5dd15e3f9cc9ba309478eec4",
  "PreviewAfterTrial": false
}

Terminate a Contract (with notice)

To terminate a contract and have billwerk honor the notice period, you need to query a cancellation preview, then proceed as in the case of an irregular cancellation, i.e.:

Sample Request
GET /contracts/:contractId/cancellationPreview
{
  "NextPossibleCancellationDate": "2018-02-07T23:00:00Z",
  "EndDate": "2018-02-08T23:00:00Z", //You'll want to post this EndDate later
  "Invoice": {...},
  "ContractAfter": {...}
}
POST /contracts/:contractId/end
{
  "EndDate": "2018-02-08T23:00:00Z"
}

Terminate a Contract (not honoring the notice period)

Sample Request

POST /contracts/:contractId/end
{
  "EndDate": "2018-02-08T23:00:00Z"
}

The EndDate must satisfy two contraints:
  • It must be greater than the contract's StartDate, i.e. you can't currently 'delete' a contract that hasn't started yet.

COMPONENT SUBSCRIPTIONS

Adding/Removing component subscriptions only

Sample Request
POST /Orders
{
  "TriggerInterimBilling": false,
  "ContractId": "5dd15e3f9cc9ba309478eec4",
  "Cart": {
    "InheritStartDate": false,
    "ComponentSubscriptions": [
      {
        "ComponentId": "5dd15e3f9cc9ba309478eedd",
        "Quantity": 2.0
      }
    ],
    "EndComponentSubscriptions": [
      "5dd15e3f9cc9ba309478eee4",
      "5dd15e3f9cc9ba309478eee5"
    ]
  },
  "PreviewAfterTrial": false
}

If you simply want to add/remove component subscriptions and keep the current plan variant you can do so by omitting the planVariantId. Creating an order this way will keep future billing times. An instant intermediate billing will be done instead.

Remove ComponentSubscriptions, EndComponentSubscriptions from the sample request as required.

Sample Response
{
  "Id": "5dd15e3f9cc9ba309478eef0",
  "AllowWithoutPaymentData": true,
  "ComponentSubscriptions": [
    {
      "ComponentType": "QuantityBased",
      "PreventModification": false,
      "VatPercentage": 19.0,
      "TotalNet": 2.0,
      "TotalVat": 0.38,
      "IsQuantityBased": false,
      "ComponentId": "5dd15e3f9cc9ba309478eedd",
      "Quantity": 2.0
    }
  ],
  "Total": 7.0,
  "TotalVat": 1.33,
  "TotalGross": 0.0,
  "NextTotalGross": 0.0,
  "IsTrial": false,
  "TrialEndPolicy": "NoTrial",
  "Status": "InProgress",
  "OrderType": "Signup",
  "TriggerInterimBilling": false,
  "CustomerId": "5dd15e3f9cc9ba309478eef1",
  "ContractId": "5dd15e3f9cc9ba309478eec4",
  "PreviewAfterTrial": false
}

In-/Decreasing quantity

Sample Request
POST /Orders
{
  "TriggerInterimBilling": false,
  "ContractId": "5dd15e3f9cc9ba309478eec4",
  "Cart": {
    "InheritStartDate": false,
    "ComponentSubscriptions": [
      {
        "ComponentId": "5dd15e3f9cc9ba309478eedd",
        "Quantity": 4.0
      }
    ],
    "EndComponentSubscriptions": [
      "5dd15e3f9cc9ba309478eedd"
    ]
  },
  "PreviewAfterTrial": false
}

If you simply want to change the quantity of a subscribed component, there is a shortcut. Subscribe to a component with the new quantity. In EndComponentSubscription pass the component id instead of listing component subscription ids. All corresponding subscriptions will be finished. The new subscription will be the only existing one for the component.

Sample Response
{
  "Id": "5dd15e3f9cc9ba309478eef2",
  "AllowWithoutPaymentData": true,
  "ComponentSubscriptions": [
    {
      "ComponentType": "QuantityBased",
      "PreventModification": false,
      "VatPercentage": 19.0,
      "TotalNet": 4.0,
      "TotalVat": 0.76,
      "IsQuantityBased": false,
      "ComponentId": "5dd15e3f9cc9ba309478eedd",
      "Quantity": 4.0
    }
  ],
  "Total": 7.0,
  "TotalVat": 1.33,
  "TotalGross": 0.0,
  "NextTotalGross": 0.0,
  "IsTrial": false,
  "TrialEndPolicy": "NoTrial",
  "Status": "InProgress",
  "OrderType": "Signup",
  "TriggerInterimBilling": false,
  "CustomerId": "5dd15e3f9cc9ba309478eef3",
  "ContractId": "5dd15e3f9cc9ba309478eec4",
  "PreviewAfterTrial": false
}

Override for components

“Override for components” is a feature that allows you to overwrite both the price and the description for the component used when you pass a component to billwerk. This gives you more flexibility in structuring your product catalog. Right now, the feature is only available for metered usages as well as components. Due to security reasons this is REST-API exclusive.

Sample Request
POST /Contracts/{contractId}/componentSubscriptions
{
  "ComponentId": "5ca70a5b50abb74c34daf308",
  "Quantity": 1,
  "ProductOverride": {
      "PricePerUnit": 23,
      "Name": "Component_v2.0",
      "Description": "Hey, I'm an overridden component"
  } 
}
Sample Response
{
    "Id": "5ca70a7b50abb74c34daf315",
    "ContractId": "5ca4b06750abb730802f9e91",
    "CustomerId": "5ca4b06750abb730802f9e90",
    "ComponentId": "5ca70a5b50abb74c34daf308",
    "Quantity": 1,
    "StartDate": "2019-04-05T07:57:47.9008963Z",
    "ProductOverride": {
        "PricePerUnit": 23,
        "Name": "Component_v2.0",
        "Description": "Hey, I'm an overridden component"
    }
}

Metered Usage

Bill metered usage

Metered usage will be billed even from previous billing periods, so you can simply post it with the correct DueDate, even if far in the past. If DueDate < LastBillingDate, then will we not interact with free quota. It is possible this will change in the future.

Override for metered usage

“Override for metered usage” is a feature that allows you to overwrite both the price and the description for the metered usage used when you pass a metered usage to billwerk. This gives you more flexibility in structuring your product catalog. Right now, the feature is only available for metered usages as well as components. Due to security reasons this is REST-API exclusive.

Sample Request
POST /Contracts/{contractId}/usage
{
  "ComponentId": "5ce53069443e551b9caccc64",
  "Quantity": 1,
  "DueDate": "2019-05-21T06:11:34.0000000Z",
  "ProductOverride": {
      "PricePerUnit": 100,
      "Name": "MeteredUsage2.0",
      "Description": "Hey, I'm an overridden metered usage"
  } 
}
Sample Response
{
    "Id": "5ce530b9443e5522685f2e93",
    "ContractId": "5cd186af443e551fe8e4f5dd",
    "TransferredAt": "2019-05-22T11:21:29.0000000Z",
    "ComponentId": "5ce53069443e551b9caccc64",
    "Quantity": 1,
    "Key": "",
    "DueDate": "2019-05-21T06:11:34.0000000Z",
    "ProductOverride": {
        "PricePerUnit": 100,
        "Name": "MeteredUsage2.0",
        "Description": "Hey, I'm an overridden metered usage"
    }
}

DISCOUNTS

Adding discounts

Adding discounts to an order is equivalent to adding a component. It can be applied to signup and up-/downgrade orders. Specifying a start date is optional.

Sample Request (direct discount)
POST /Orders
{
  "TriggerInterimBilling": false,
  "ContractId": "5dd15e3f9cc9ba309478eec4",
  "Cart": {
    "InheritStartDate": false,
    "DiscountSubscriptions": [
      {
        "StartDate": "2019-11-19T14:50:39.7497178Z",
        "DiscountId": "5dd15e3f9cc9ba309478eede"
      }
    ]
  },
  "PreviewAfterTrial": false
}

The example shows adding a discount to an upgrade order

Sample Response
{
  "Id": "5dd15e3f9cc9ba309478eef6",
  "AllowWithoutPaymentData": false,
  "Total": 10.0,
  "TotalVat": 1.9,
  "TotalGross": 0.0,
  "NextTotalGross": 0.0,
  "IsTrial": false,
  "TrialEndPolicy": "NoTrial",
  "Status": "InProgress",
  "OrderType": "Signup",
  "TriggerInterimBilling": false,
  "CustomerId": "5dd15e3f9cc9ba309478eef7",
  "ContractId": "5dd15e3f9cc9ba309478eec4",
  "PreviewAfterTrial": false
}

Adding discounts via coupon is only available in signup orders. The discount the coupon code is assigned to will be applied.

The example shows adding a discount to an upgrade order

Sample Response
{
  "Id": "5dd15e3f9cc9ba309478eef6",
  "AllowWithoutPaymentData": false,
  "Total": 10.0,
  "TotalVat": 1.9,
  "TotalGross": 0.0,
  "NextTotalGross": 0.0,
  "IsTrial": false,
  "TrialEndPolicy": "NoTrial",
  "Status": "InProgress",
  "OrderType": "Signup",
  "TriggerInterimBilling": false,
  "CustomerId": "5dd15e3f9cc9ba309478eef7",
  "ContractId": "5dd15e3f9cc9ba309478eec4",
  "PreviewAfterTrial": false
}

Adding discounts via coupon

Sample Request
POST /Orders
{
  "TriggerInterimBilling": false,
  "Cart": {
    "PlanVariantId": "5dd15e3f9cc9ba309478eee7",
    "InheritStartDate": false,
    "CouponCode": "ABCDEF"
  },
  "Customer": {
    "CompanyName": "ACME Inc.",
    "FirstName": "John",
    "LastName": "Doe",
    "VatId": "DE424324234",
    "EmailAddress": "john.doe@example.com",
    "Address": {
      "AddressLine1": "c/o Coworking Ltd.",
      "Street": "Zschopauer Straße",
      "HouseNumber": "42",
      "PostalCode": "10123",
      "City": "Berlin",
      "Country": "DE"
    },
    "Hidden": false
  },
  "PreviewAfterTrial": false
}

MISCELLANEOUS

Using Rated Items

Rated items can be used to transfer invoice items to billwerk that have been named and priced in other systems. The invoice items transferred in this way are taken into account in the next settlement and included in the invoice together with the items generated by billwerk. Use this method to bill products and services for which there is no standard pricing and which are not part of the product catalog in your billwerk account.


Processing an order in the future

By default orders are processed instantly after the commit. Orders for existing contracts can also be processed in the future by passing the ChangeDate

Sample Request
POST /Orders
{
  "ChangeDate": "2019-12-07T14:50:39.752646Z",
  "TriggerInterimBilling": false,
  "ContractId": "5dd15e3f9cc9ba309478eec4",
  "Cart": {
    "PlanVariantId": "5dd15e3f9cc9ba309478eee6",
    "InheritStartDate": false
  },
  "PreviewAfterTrial": false
}
Sample Response
{
  "Id": "5dd15e3f9cc9ba309478eef4",
  "AllowWithoutPaymentData": false,
  "Total": 10.0,
  "TotalVat": 1.9,
  "TotalGross": 0.0,
  "NextTotalGross": 0.0,
  "IsTrial": false,
  "TrialEndPolicy": "NoTrial",
  "Status": "InProgress",
  "OrderType": "Signup",
  "TriggerInterimBilling": false,
  "CustomerId": "5dd15e3f9cc9ba309478eef5",
  "ContractId": "5dd15e3f9cc9ba309478eec4",
  "PreviewAfterTrial": false
}