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

Terminate a Contract (not honoring the notice period)

POST /contracts/:contractId/end
{ EndDate: "2014-06-12T14:29:11.9820000Z" }

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

Terminate a Contract (with notice)

To terminate a contract and have billwerk consider the notice period, you need to query a cancellation preview, then proceed as in the case of an irregular cancellation, i.e.:
GET /contracts/:contractId/cancellationPreview
{
    "NextPossibleCancellationDate":"2014-06-27T15:51:23.4840000Z",
    "EndDate":"2014-06-28T15:51:23.4840000Z",
    "Invoice":{ ... },
    "ContractAfter":{ ... }
}

POST /contracts/:contractId/end
{ EndDate: "2014-06-28T15:51:23.4840000Z" }

Terminate a ComponentSubscription

This can currently be achieved by performing a PUT request that sets the EndDate of the subscription to a certain point in time:
GET /contracts/:contractId/componentSubscriptions
[{
  "Id" : "542ef24a9e40073bd459af61",
  "ContractId" : "538a3919824007afcc7b2d9b",
  "CustomerId" : "539a331d6e4000944c7b2dc2",
  "ComponentId" : "53862fdd9e400737a4800567",
  "Quantity" : 1,
  "StartDate" : "2014-05-02T08:55:12.0000000Z",
}, ... ]

PUT /componentSubscriptions/:componentSubscriptionId
{
  "Id" : "542ef24a9e40073bd459af61",
  "ContractId" : "538a3919824007afcc7b2d9b",
  "CustomerId" : "539a331d6e4000944c7b2dc2",
  "ComponentId" : "53862fdd9e400737a4800567",
  "Quantity" : 1,
  "StartDate" : "2014-05-02T08:55:12.0000000Z",
  "EndDate":"2014-06-01T00:00:00.000Z"
}
Please be aware that the EndDate must be greater than or equal both the component subscriptions' StartDate and the BilledUntil value, if present. A component subscription will have a BilledUntil value if it has ever been billed, while component subscriptions that have never come into effect don't have this value set.

Bill metered usage from previous months

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. However, it is unclear how this is supposed to interact with free quota.

Create a second contract for a 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

The first step is to create the order

POST /orders
{
    "CustomerID" : "customerid",
    "Cart" :
    {
        "PlanVariantId" : "planvariantid"
    }
}

This call will return a full order object, which is omitted here for brevity. What matters for this discussion is that you get an ID for the order.

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 BillwerkJS again.

BillwerkJS offers a method paySignupInteractive(billwerkJSPayment, secretPaymentData, order, success, error) that you can use to perform the interactive payment of an order. This method is internally called by BillwerkJS'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.