Payment Processing

Rest assured, you can hook up your own payment processing to Hurdlr's Invoicing API. If you are using Stripe or Moov for payment processing, then you can simply share your Stripe or Moov credentials with Hurdlr, and the Hurdlr API will take care of the rest.

If you'd like to use a payment processor other than Stripe or Moov, you can do so by performing the steps detailed below.

1. Getting started

Hurdlr recognizes that payment processing is critical to the business model of many FinTechs. As such, the Hurdlr API allows you to connect your existing accounts, from any payment processor, including but not limited to:

  1. Stripe (native integration, which requires simply sharing keys)
  2. Moov (native integration, which requires simply sharing keys)
  3. Maast (native integration, which requires simply sharing keys)
  4. ProPay
  5. PayPal
  6. Square
  7. Braintree
  8. WePay

The Hurdlr API team can help you securely connect your existing payment processing accounts; simply email us at [email protected].

2. How it works

If you have already implemented your own payment processing mechanism (e.g. to allow your users to accept credit card payments, ACH, etc.), then you'll want to follow the steps outlined below to get your payment processing integrated with the Hurdlr API.

Once integrated, your users will be able to send out invoices, and their clients will be able to pay those invoices using your payment processor of choice. Your back-end will communicate with the Hurdlr API to let it know of any updates to payments.

The Hurdlr API, as always, will take care of all the double-entry accounting behind the scenes. And the burden of creating a robust invoicing engine to pair with your payment processing is taken off of your dev team's shoulders.

👍

Automatic income reconciliation

Once you hook up your users' income data sources (e.g. bank accounts) to Hurdlr, Hurdlr's algorithms will automatically find and reconcile the bank deposits to the associated invoice payments (from your payment processor), in real-time.

3. Creating a merchant account for your user

When connecting a third party payment processor to the Hurdlr API, you own the experience around creating a merchant for your user. As such, the UX for creating a merchant account sits inside your product.

If you are using Hurdlr's Embeddable Invoice Dashboard, then you will also need to register a listener. By registering a listener, the Hurdlr SDK will invoke the callback function you provide when users perform key actions, so that you can route the user to the proper place within your own UI.

To register the listener, simply add the following line of JS to be ran once after Hurdlr.init({...}):

Hurdlr.registerPaymentProcessingListener(myPaymentProcessingCallback);

The two key interactions that will invoke your callback function are:

a) the user presses a CTA to set up their payment processing
b) the user presses a CTA to refund an invoice that was already paid for through your payment processing

Now that you have registered the listener, you are ready to handle when a user wants to set up payment processing (e.g. to accept credit card payments). Whenever a user presses a CTA to set up payment processing, myPaymentProcessingCallback will be invoked with a JSON object as the single argument.

When that CTA is clicked, we recommend you take the following actions:

a) route the user to your payment processing (or merchant account creation) flow, so they can complete their merchant setup
b) once complete, update the user's invoice setup record to set thirdPartyPaymentsEnabled to true

An example implementation of myPaymentProcessingCallback is shown below:

var myPaymentProcessingCallback = (data) => {
  switch (data.type) {
    case Hurdlr.SETUP_PAYMENT_PROCESSING:
      // route user to my existing payment processing setup flow
      // once complete, POST to /invoiceSetup to set { invoiceSetupComplete: true, thirdPartyPaymentsEnabled: true }
      break;
    case Hurdlr.REFUND_INVOICE:
      break;
  }
  // route back to my app's invoice dashboard screen
}

Hurdlr.registerPaymentProcessingListener(myPaymentProcessingCallback);

4. Processing a payment

If you are using Hurdlr's Embeddable Client-facing Invoice, then you will also need to register a listener. By passing in a paymentCallbackFunction into the Hurdlr.renderClientInvoice() function, the Hurdlr SDK will invoke the callback function you provide when the user's client performs key actions, such as pressing a CTA to pay the invoice, so that you can route the user to the proper place within your own UI.

When the "pay invoice" CTA is clicked, we recommend you take the following actions:

a) route the user to your payment capture flow
b) process the payment for the specific invoice (using data.invoiceId) via your payment processor
c) alert the Hurdlr API that the payment was processed

An example implementation of myClientInvoiceCallback is shown below:

var myClientInvoiceCallback = ({ type, invoiceId, invoiceName, invoiceBalance }) => {
  switch (type) {
    case Hurdlr.PAY_INVOICE:
      // route user to my existing payment capture flow
      // process the payment with my payment processor, for invoice with id===invoiceId
      // once complete, POST the payment to /payment
      break;
  }
}

Hurdlr.renderClientInvoice("myDiv", { paymentCallbackFunction: myClientInvoiceCallback });

Whenever you process a payment for a finalized invoice, you should let the Hurdlr API know that you've done so by assembling the following fields in a JSON object:

FieldDescriptionFormat
invoiceIdId of the invoice to mark paidNumeric
grossPaymentAmountTotal amount paid by the clientNumeric, with 2 decimal places
feePaymentAmountService fee to process the payment (subtracted out of the grossPaymentAmount)Numeric, with 2 decimal places
apiPaymentIdId of the payment in your DB (or from your payment processor)Any string
paymentSourceDisplay name for the paymentAny string (e.g. "Visa *4747 Charge")
statusStatus of the payment (especially useful for ACH)Must be one of the following:
"PENDING", "PROCESSED", "CANCELED", "REFUNDED", "FAILED"

To mark the invoice as paid, simply POST the above JSON object to the /payment endpoint:

curl \
  --request POST \
  --url https://sandbox.hurdlr.com/rest/v5/invoicing/payment \
  --header 'Authorization: Bearer ${access_token}' \
  --header 'Content-Type: application/json' \
  --data '{
    "payment": {
      "invoiceId": 21850,
      "grossPaymentAmount": 150.00,
      "feePaymentAmount": 4.50,
      "apiPaymentId": "ch_3KX9F5KkMq1CsF5K00DChQgZ",
      "paymentSource": "Visa *4747 Charge",
      "status": "PROCESSED"
    }
  }'

5. Refunding a payment

Now that you have registered the listener, you are ready to handle when a user wants to refund a paid invoice. Whenever a user presses a CTA to refund a paid invoice, myPaymentProcessingCallback will be invoked with a JSON object as the single argument.

When that CTA is clicked, we recommend you take the following actions:

a) process the refund for the specific invoice (using data.invoiceId) via your payment processor
b) alert the Hurdlr API that the refund was processed, by marking the invoice as refunded

An example implementation of myPaymentProcessingCallback is shown below:

var myPaymentProcessorCallback = ({ type, invoiceId }) => {
  switch (type) {
    case Hurdlr.SETUP_PAYMENT_PROCESSING:
      // route user to my existing payment processing setup flow
      // once complete, POST to /invoiceSetup to set { invoiceSetupComplete: true, thirdPartyPaymentsEnabled: true }
      break;
    case Hurdlr.REFUND_INVOICE:
      // process the refund with my payment processor, for invoice with id===invoiceId
      // once complete, POST the refunded payment to /payment
      break;
  }
  // route back to my app's invoice dashboard screen
}

Hurdlr.registerPaymentProcessingListener(myPaymentProcessingCallback);

Whenever you issue a refund for a payment that you processed, you should let the Hurdlr API know that you've done so by assembling the following fields in a JSON object:

FieldDescriptionFormat
apiPaymentIdId of the payment in your DB (or from your payment processor)Numeric

To mark the payment as refunded, simply POST the above JSON object to the /payment endpoint:

curl \
  --request POST \
  --url https://sandbox.hurdlr.com/rest/v5/invoicing/payment \
  --header 'Authorization: Bearer ${access_token}' \
  --header 'Content-Type: application/json' \
  --data '{
    "payment": {
      "apiPaymentId": "ch_3KX9F5KkMq1CsF5K00DChQgZ",
      "status": "REFUNDED"
    }
  }'

6. Sending a payment receipt

To send a payment receipt to the client, you can simply make a POST call to the /sendReceipt endpoint:

curl \
  --request POST \
  --url https://sandbox.hurdlr.com/rest/v5/invoicing/sendReceipt \
  --header 'Authorization: Bearer ${access_token}' \
  --header 'Content-Type: application/json' \
  --data '{
    "invoiceIds": [
        21850
    ]
  }'

If you'd like these emails to originate from your own domain, simply email [email protected] and our API team will work with you to set that up.

7. Recurring Invoices

Hurdlr's Invoicing API makes creating recurring invoices easy, as detailed in the Creating an Invoice Draft section. The recurrence itself is managed via the Hurdlr API, not your payment processor. So even if your payment processor doesn't support recurring payments, you can utilize Hurdlr's API on top of your payment processor to easily add that functionality.