Skip to content

Billing

BillingInvoice represents a customer's or patient's payables.

Invoice, Items, and Payments

Each BillingInvoice can contain multiple BillingItems to represent each line item that must be paid by a customer or patient. Each BillingItem can also have one or more BillingPayment to represent each payment type and amount a customer or patient made for a specific BillingItem. Each BillingItem must be added to the BillingInvoice before finalizing it while BillingPayments can be made event after finalizing the BillingInvoice.

sh
# create an invoice
invoice = POST /billing-invoices {
  facility: <facility-id>
  type: 'medical-encounter',
  subject: <px-id>,
  subjectType: 'medical-patient',
}

# add a line item
item = POST /billing-items {
  invoice: <invoice-id>,
  type: 'service',
  ref: <service-id>,
  price: <service-price>,
}

# add a payment on the item
payment = POST /billing-payments {
  item: item.id,
  type: 'private',
  paymentMethod: 'CASH',
  amount: <payment-amount>
}
# create an invoice
invoice = POST /billing-invoices {
  facility: <facility-id>
  type: 'medical-encounter',
  subject: <px-id>,
  subjectType: 'medical-patient',
}

# add a line item
item = POST /billing-items {
  invoice: <invoice-id>,
  type: 'service',
  ref: <service-id>,
  price: <service-price>,
}

# add a payment on the item
payment = POST /billing-payments {
  item: item.id,
  type: 'private',
  paymentMethod: 'CASH',
  amount: <payment-amount>
}

Creating Invoice

A billing invoice can be created either by using the billing-invoices API's create method or by creating a MedicalEncounter with invoice: true on its payload.

Notes

Created BillingInvoices are drafts until finalized.

Finalizing Invoice

BillingInvoices should be marked as finalized at the end of the actual patient visit as it would cascade to finalizing the associated BillingItems created during the visit (they would be considered drafts otherwise). To finalize an BillingInvoice, a special patch operator finalize: true can be use in the medical-encounters API's patch method.

Removing Invoice

Deleting an invoice will also delete all associated BillingItems (w/c would also delete all associated BillingPayments)

Creating Invoice Items

Created BillingItems are drafts until finalized either via directly finalizing the BillingItem or via the cascading effect of finalizing an BillingInvoice.

Creating Payments

BillingPayments can be created even after finalizing a BillingInvoice. Multiple BillingPayments can be created for a specific BillingItem to represent patient payments or multiple payment methods but the total amount cannot exceed the total payable amount of a BillingItem.

Billing Customers

Creating a basic BillingCustomer attached to the creator account

sh
POST /billing/customers
{
  owner: {
    account: <my-uid>
  }
}
POST /billing/customers
{
  owner: {
    account: <my-uid>
  }
}

Creating a BillingCustomer with a default payment source

sh
POST /billing/customers
{
  owner: {
    account: <my-uid>
  },
  stripeToken: <stripe-token-from-stripe-api>,
  # optional
  stripeEmail: <email-address-to-register-in-stripe>
}
POST /billing/customers
{
  owner: {
    account: <my-uid>
  },
  stripeToken: <stripe-token-from-stripe-api>,
  # optional
  stripeEmail: <email-address-to-register-in-stripe>
}

Creating a BillingCustomer for an organization

sh
POST /billing/customers
{
  owner: {
    organization: <my-org-w/c-i-am-superadmin-of>
  },
  stripeToken: <stripe-token-from-stripe-api>,
  # optional
  stripeEmail: <email-address-to-register-in-stripe>
}
POST /billing/customers
{
  owner: {
    organization: <my-org-w/c-i-am-superadmin-of>
  },
  stripeToken: <stripe-token-from-stripe-api>,
  # optional
  stripeEmail: <email-address-to-register-in-stripe>
}

Populating saved cards of a BillingCustomer

sh
GET /billing/customers/<customer-id>?$populateStripeCards=true

# response
{
  ...customer details
  stripeCustomerCards: {
    data: [{
      id: <stripe-card-id>,
      ...other card details
      # see card details @ https://stripe.com/docs/api/cards/object
    }],
  },
}
GET /billing/customers/<customer-id>?$populateStripeCards=true

# response
{
  ...customer details
  stripeCustomerCards: {
    data: [{
      id: <stripe-card-id>,
      ...other card details
      # see card details @ https://stripe.com/docs/api/cards/object
    }],
  },
}

Saving additional card (w/c would automatically become the default)

sh
PATCH /billing/customers/<customer-id>
{
  stripeToken: <stripe-token-from-stripe-api>,
}
PATCH /billing/customers/<customer-id>
{
  stripeToken: <stripe-token-from-stripe-api>,
}

Deleting a saved card (if default, will change the default to the next registerd source)

sh
PATCH /billing/customers/<customer-id>
{
  # where <stripe-card-id> can be found after populating
  # the saved cards in a `BillingCustomer`
  $deleteStripeCard: <stripe-card-id>,
}
PATCH /billing/customers/<customer-id>
{
  # where <stripe-card-id> can be found after populating
  # the saved cards in a `BillingCustomer`
  $deleteStripeCard: <stripe-card-id>,
}

Setting a different saved card as the default

sh
PATCH /billing/customers/<customer-id>
{
  # where <stripe-card-id> can be found after populating
  # the saved cards in a `BillingCustomer`
  $setDefaultStripeCard: <stripe-card-id>,
}
PATCH /billing/customers/<customer-id>
{
  # where <stripe-card-id> can be found after populating
  # the saved cards in a `BillingCustomer`
  $setDefaultStripeCard: <stripe-card-id>,
}

Billing Payment Intents

sh
# create payment intent with specific gateway
POST /billing-payment-intents
{
  gatewayType: 'paymongo-gcash',
  # you can also specify/override the default
  # return/cancel url
  gatewayReturnURL: 'http://localhost/return',
  gatewayCancelURL: 'http://localhost/cancel',
  currency: 'PHP',
  items: [
    # reference an existing variant
    {
      type: 'inventory-variant',
      ref: '<varian.sku>',
      quantity: 1,
    },
    # reference an existing service
    {
      type: 'service',
      ref: '<service.id>',
      quantity: 1,
    },
    # or specify a custom item
    {
      name: 'Custom 1',
      amountPerItem: 100,
      quantity: 1,
    },
  ]
}

# make user approve the payment via the given url
# result.checkout.approvalURL

# after approval, payment can be manually captured via
PATCH /billing-payment-intents/<result.id>
{ capture: true }
# create payment intent with specific gateway
POST /billing-payment-intents
{
  gatewayType: 'paymongo-gcash',
  # you can also specify/override the default
  # return/cancel url
  gatewayReturnURL: 'http://localhost/return',
  gatewayCancelURL: 'http://localhost/cancel',
  currency: 'PHP',
  items: [
    # reference an existing variant
    {
      type: 'inventory-variant',
      ref: '<varian.sku>',
      quantity: 1,
    },
    # reference an existing service
    {
      type: 'service',
      ref: '<service.id>',
      quantity: 1,
    },
    # or specify a custom item
    {
      name: 'Custom 1',
      amountPerItem: 100,
      quantity: 1,
    },
  ]
}

# make user approve the payment via the given url
# result.checkout.approvalURL

# after approval, payment can be manually captured via
PATCH /billing-payment-intents/<result.id>
{ capture: true }

Analytics types

  • net-amount-total summate the netAmount field of all selected payment intents
  • receivables-total summate the receivables.* fields of all selected payment intents

Released under the MIT License.