Accepting a Bank Payment on your Website

Accepting Bank Payments on Your Website with Stax.js

Accepting a payment using a card is identical to tokenizing a card but will also take payment from the tokenized card. You can also include additional details within the call to take advantage of Level 2 processing.


Setting Up Stax.js on Your Website

Adding the Stax.js Script

  1. Add the following script tag to the head of your HTML file.
  2. <script src="https://staxjs.staxpayments.com/staxjs-captcha.js"></script>

Initializing Your Payment Instance

Before you can process payments, you need to initialize Stax.js with your credentials:

  1. First, you must know your Web Payments Token (public key) within Stax Pay by navigating to Apps > API Keys.
  2. Initialize your Stax.js instance with the StaxJs class using your website payments token, like in the examples below.

Security Note: Passing the number and CVV into the instance of Stax.js generates the secure iframe around these two fields, keeping sensitive card information from touching your servers.

// Initialize Stax.js with your public token
var staxjs = new StaxJs("your_website_payments_token", {});

Creating Your Payment Form Interface

Create a payment form to capture the card and routing numbers and create a Tokenize button. This form will serve as the foundation for collecting customer payment information securely.

Configuring Secure Payment Fields

Now that we've initialized our instance of StaxJs and made the elements that will contain the credit card fields, we can tell StaxJs to load in those credit card fields. The showCardForm function returns a Promise, which lets us handle the completion of the credit card fields loading in.

Managing Form Validation Events

Stax.js provides built-in handlers to check for field input validity, ensuring a smooth user experience:

Handling Invalid Input: First, we will handle the card_form_uncomplete event, which means that the input within the fields is invalid.

Handling Valid Input: Next, we'll handle the card_form_complete event, which means that the input within the fields is complete and valid.

Processing Bank Payments with Enhanced Data

When taking a payment on a site, you can include additional details in the meta data to qualify for better processing rates and enhanced functionality.

Payment Parameters Reference

FieldDescriptionRequired
metaobjectNo
meta.tax(float) This tax dollar amount value must be a numeric value representing 0.1% and 30% of the transaction's total in order to qualify for L2 processing rates.No
meta.shippingAmount(float) Shipping cost for the transactionNo
meta.poNumber(string) This customer code or identifier, sometimes called the PO number, is used to qualify for L2 processing rates.No
meta.invoice_merchant_custom_fieldsAn array containing custom field objects. See the Example Below for more information. These custom fields will only appear if your account subscribes to the Advanced Customization add-on. To enable this feature, please reach out to your Account Manager.No
totalrequired when using the pay() method, must be a numberYes
urlnot required; this represents the hosted URL where this paid invoice can be viewed when the invoice's ID is appended to it. See here for an example of what a hosted paid invoice looks like.No
send_receiptnot required, boolean, defaults to true. When set to true an email will be sent every time the pay() method is called from your application – even if the transaction is unsuccessful. If the transaction is unsuccessful (for whatever reason), an email will be sent, which will include a call to action to pay using the Stax-hosted payments solution. Alternatively, if you use the out-of-the-box Stax email solution but would like more control over when a receipt email is sent, you can use the Transactions resource to send the receipt via email or sms.No
match_customerBoolean. Determines whether or not Stax.js matches the customer to an existing customer based on some combination of the same data sent into the JS request. See Best Practices: Customer Matching section for more details.No

Complete Payment Processing Example

This example demonstrates how to process a bank payment with comprehensive customer and transaction details:

// Define all payment details including customer information and metadata
const paymentDetails = {
  total: 10,
  firstname: "John",
  lastname: "Doe",
  person_name: "John Doe",
  method: "bank",
  bank_type: "savings",
  bank_name: "Bank INC",
  bank_account: "9876543210",
  bank_routing: "021000021",
  bank_holder_type: "personal",
  phone: "5555555555",
  address_1: "100 S Orange Ave",
  address_2: "Suite 400",
  address_city: "Orlando",
  address_state: "FL",
  address_zip: "32811",
  address_country: "USA",
  send_receipt: false,
  match_customer: false,
  validate: false,
  meta: {
    reference: "invoice-reference-num", // Shows up in emailed receipts
    memo: "notes about this transaction", // Shows up in emailed receipts
    otherField1: "other-value-1", // Custom tracking field
    otherField2: "other-value-2", // Custom tracking field
    subtotal: 1, // Shows up in emailed receipts
    tax: 0, // Required for Level 2 processing rates
    lineItems: [
      // Itemized details for receipts
      {
        id: "optional-fm-catalog-item-id",
        item: "Demo Item",
        details: "this is a regular demo item",
        quantity: 10,
        price: 0.1,
      }
    ],
    invoice_merchant_custom_fields: [
      {
        id: "dc4b-6c74-00dd-fab1-fe00", // Required unique identifier
        name: "External ID", // Display label for the field
        placeholder: "Ex. #123", // Helper text for users
        required: true, // Whether field must be completed
        type: "text", // Input type (only 'text' supported)
        value: "123456789", // The actual field value
        visible: true, // Whether visible in customer-facing views
      },
    ],
  },
};

Executing the Payment Transaction

Once your payment details are configured, you can process the payment using the pay() method:

// Process the payment when user clicks the pay button
document.querySelector("#paybutton").onclick = () => {
  staxjs
    .pay(paymentDetails)
    .then((response) => {
      console.log("invoice object:", response);
      console.log("transaction object:", response.child_transactions[0]);
      // Handle successful payment here
    })
    .catch((err) => {
      console.log("unsuccessful payment:", err);
      // Handle payment errors here
    });
};

Understanding the Payment Response Structure

A successful call to the Stax.js pay() method creates a tokenized payment method tied to a new or existing customer, generates an invoice using the provided details, and processes a transaction that pays the invoice in full.

The response contains the complete invoice object, including references to the customer, payment method, and transaction. To access transaction-specific information, use response.child_transactions[0].

Complete Invoice Response Example

Here's what a successful payment response looks like:

{
  "balance_due": 0,
  "child_transactions": [
    {
      "auth_id": null,
      "created_at": "2020-07-01 00:17:08",
      "customer_id": "e8978baa-0278-47c2-9036-2849c6f522e1",
      "id": "0a40f1a9-f308-4add-8613-91f717b52831", // Transaction ID
      "invoice_id": "101c4a15-5cdb-41e5-837c-f23470c7d670",
      "is_manual": false,
      "is_merchant_present": false,
      "issuer_auth_code": null,
      "message": null,
      "meta": {
        "memo": "notes about this transaction",
        "otherField1": "other-value-1",
        "otherField2": "other-value-2"
      },
      "method": "card",
      "payment_method": {
        "id": "68ad2229-18ab-47d5-8713-2f4cf109af55",
        "customer": null
      },
      "payment_method_id": "68ad2229-18ab-47d5-8713-2f4cf109af55",
      "receipt_email_at": null,
      "receipt_sms_at": null,
      "reference_id": "",
      "source": null,
      "success": true,
      "total": 1,
      "type": "charge",
      "updated_at": "2020-07-01 00:17:08"
    }
  ],
  "created_at": "2020-07-01 00:17:08",
  "customer": {
    "address_1": "100 S Orange Ave",
    "address_2": "",
    "address_city": "Orlando",
    "address_country": "USA",
    "address_state": "FL",
    "address_zip": "32811",
    "allow_invoice_credit_card_payments": true,
    "cc_emails": null,
    "cc_sms": null,
    "company": "",
    "created_at": "2020-07-01 00:17:07",
    "deleted_at": null,
    "email": "",
    "firstname": "Jon",
    "gravatar": false,
    "id": "e8978baa-0278-47c2-9036-2849c6f522e1", // Customer ID
    "lastname": "Doe",
    "notes": null,
    "options": null,
    "phone": "111111111111111",
    "reference": "",
    "updated_at": "2020-07-01 00:17:07"
  },
  "customer_id": "e8978baa-0278-47c2-9036-2849c6f522e1",
  "deleted_at": null,
  "due_at": null,
  "id": "101c4a15-5cdb-41e5-837c-f23470c7d670", // Invoice ID
  "invoice_date_at": "2020-07-01 00:17:08",
  "is_merchant_present": null,
  "is_partial_payment_enabled": true,
  "is_webpayment": true,
  "meta": {
    "lineItems": [
      {
        "details": "this is a regular, demo item",
        "id": "optional-fm-catalog-item-id",
        "item": "Demo Item",
        "price": 0.1,
        "quantity": 10
      }
    ],
    "memo": "notes about this transaction",
    "otherField1": "other-value-1",
    "otherField2": "other-value-2",
    "reference": 1988,
    "subtotal": 1,
    "tax": 0
  },
  "paid_at": "2020-07-01 00:17:10",
  "payment_attempt_failed": false,
  "payment_attempt_message": "",
  "payment_method_id": "68ad2229-18ab-47d5-8713-2f4cf109af55",
  "schedule_id": null,
  "sent_at": null,
  "status": "PAID",
  "total": 1,
  "total_paid": 1,
  "updated_at": "2020-07-01 00:17:10",
  "url": "https://omni.fattmerchant.com/#/bill/",
  "viewed_at": null
}

Next Steps

After successfully implementing bank payments, you may want to explore: