🎉 Celebrate with 10% OFF on All Products! Use Code: GFEX10 Or Buy Any 2+ Items for 30% OFF with Code: GFEX30!

Gravity Forms BTCPay Server Premium Add-on Setup Guide

Updated 9 min read Gravity Forms Integrations A–Z
On this page
  1. Requirements
  2. Step 1: Install and activate the licence
  3. Step 2: Create an API key and the store details in BTCPay Server
  4. Step 3: Connect the add-on
  5. Step 4: Add the webhook in BTCPay Server
  6. Step 5: Currency and amounts
  7. Step 6: Create the feed
  8. How payments are confirmed
  9. Refund links
  10. Developer hooks
  11. Testing
  12. Going live
  13. Troubleshooting
  14. Uninstall

The Gravity Forms BTCPay Server Premium Add-on connects Gravity Forms to a store on your own BTCPay Server, the open-source, self-hosted payment server. When a form is submitted, the add-on creates an invoice on your server for the exact form total and sends the customer to the checkout page of your BTCPay Server, where they pay with the payment methods enabled in your store, for example Bitcoin on-chain and Lightning. This guide covers the setup, every setting, how payments are confirmed, refund links, testing and going live.

Requirements

  • WordPress 6.5 or newer, PHP 7.4 or newer, and Gravity Forms 2.9 or newer.
  • Your own BTCPay Server (version 2.x), reachable on a public https address, with a store that has at least one payment method set up (an on-chain wallet and/or a Lightning node).
  • A rate source set in your store (Store Settings → Rates) that has a rate for your Gravity Forms currency.
  • An https website, so BTCPay Server can deliver webhooks to it.
  • A GravityExtra licence key for the add-on.

Step 1: Install and activate the licence

Upload the plugin zip in Plugins → Add New → Upload Plugin, activate it, then open Forms → Settings → BTCPay Server and activate your licence key. All payment features (settings, feeds, payments, webhooks, the status check and entry actions) need a valid licence.

Step 2: Create an API key and the store details in BTCPay Server

  1. Log in to your BTCPay Server and open the store you want to use. Copy the Store ID from Store Settings → General.
  2. Open Account → Manage Account → API Keys → Generate Key. Give it a label such as “Website forms”, limit it to your store and tick View invoices, Create an invoice and, if you want refund links, Create non-approved pull payments. Generate it and copy the key.
  3. For testing, do the same on a test store, for example on a BTCPay Server that runs on testnet or regtest.

Step 3: Connect the add-on

BTCPay Server settings: Test or Live mode, the server address, store ID and masked API key and webhook secret of each mode, confirmations before Paid, invoice expiry, the currency line, the connection line and the webhook address
Settings: the address of your own BTCPay Server, the store ID, an API key and the webhook secret for each mode.

In Forms → Settings → BTCPay Server, keep the mode on Test, enter the server address, store ID and API key for Test, and save. The key is checked by listing one invoice of the store, so nothing is created. If your server refuses the key, the key cannot see the store or the store ID is unknown, you get a clear message and nothing is saved. The Connection line then shows “Connected to BTCPay Server” with the host name and the masked key.

Setting What it does
Mode Test (the default) uses the server and store you save for Test, for example a store on a testnet or regtest BTCPay Server, so no real money moves. Live uses your production server and store. Each entry remembers the mode, server and store it was created with.
Test / Live server address The https address of your BTCPay Server, for example https://pay.your-shop.com (a folder such as /btcpay is fine). Addresses that point to private or local networks are refused; a filter allows a server on your own network.
Test / Live store ID From Store Settings → General in BTCPay Server.
Test / Live API key A Greenfield API key for that store with “View invoices”, “Create an invoice” and, for refund links, “Create non-approved pull payments”. When you save, it is checked by listing one invoice of the store (nothing is created). Stored encrypted, shown masked (first and last four characters).
Test / Live webhook secret The secret of the webhook you create in Store Settings → Webhooks. Every webhook signature is checked with it. Stored encrypted, shown masked.
Confirmations before Paid The store setting, or high speed (0), medium (1), low-medium (2) or low speed (6 confirmations) for on-chain payments. Lightning payments settle at once.
Invoice expiry (minutes) Empty for the store setting (15 minutes by default), or 5 to 1,440 minutes.
Currency A check line: the Gravity Forms currency must be one the add-on can invoice.
Connection Shows whether your server accepts the key for the store of the current mode, with the masked key.
Webhook The webhook address to paste into BTCPay Server, a warning when the site is not on https, and when the last webhook with a valid signature arrived.

Step 4: Add the webhook in BTCPay Server

  1. Copy the webhook address from the Webhook line of the settings. It looks like https://your-site.com/wp-json/gravityextra-btcpay/v1/webhook.
  2. In BTCPay Server, open Store Settings → Webhooks → Create Webhook and paste the address as the payload URL.
  3. Keep “Automatic redelivery” on and either send everything or choose the invoice events (payment received, processing, settled, expired, invalid).
  4. Copy the secret shown on that page into the webhook secret field of the add-on and save both.

Why the add-on does not create the webhook for you

Creating webhooks needs an extra permission on the API key. Keeping the key to three permissions means it can view and create invoices and refund links for one store, and nothing else.

Step 5: Currency and amounts

Set the Gravity Forms currency in Forms → Settings. The add-on invoices in that currency, and BTCPay Server converts it with the rate source of your store on the checkout page. The amount sent is the exact total Gravity Forms worked out on the server, never a number from the browser.

Item Value
Currencies The 25 currencies Gravity Forms ships, for example USD, EUR, GBP, CAD, AUD, CHF, JPY. BTCPay Server converts the amount with the rate source of your store.
Decimals As in Gravity Forms: none for the Japanese yen, two for the others. A total with more decimals is refused, never rounded.
Sent to BTCPay Server as A decimal text for the exact form total, for example “285.50” or “12500” (yen)
Smallest payment 1.00 in the form currency (1 yen)
Largest payment 9,999,999.00 (a filter can lower it)

Step 6: Create the feed

The BTCPay Server feed: products and services with the form total, the customer name and email mapping, the invoice description with merge tags and notifications after payment
The feed: map the customer name and email, and write the description shown on the invoice in BTCPay Server.

Open your form, then Settings → BTCPay Server → Add New. Choose Products and Services (or Donations), the payment amount (usually the form total), map the name and email fields, and write the description shown on the invoice in BTCPay Server, for example Bike service #{entry_id}. Tick “Send form notifications only after the customer has paid” if your emails should wait for the payment.

A bike service booking form with quantities, the customer name and email, and the total of $285.50, with the Continue to payment button
The form: Gravity Forms works out the total in your currency; BTCPay Server converts it on the checkout page.

How payments are confirmed

  1. On submit, the form is checked on the server: licence, connection, currency, decimals, limits, email, the per-visitor limit and the hourly cap.
  2. An invoice is created on your server with the amount as a decimal text, the currency, a unique order ID for this attempt, the description, the customer name and email, and a signed return address.
  3. The answer must carry an invoice of your store, your order ID, the amount and currency sent, and a checkout link on the server you configured. Otherwise the customer stays on the form and is told nothing was charged.
  4. When a webhook arrives, its BTCPay-Sig signature is checked with your webhook secret. A valid webhook is only a signal: the invoice is then read back from your server.
  5. The same read-back runs when the customer returns, every five minutes and when you click Refresh status on the entry.
  6. Only a Settled invoice with the entry amount, currency, store and order ID marks the entry Paid. The payment method and payment IDs are added to the note.
BTCPay Server invoice Entry
New (not paid yet) Processing. After three days without a payment the entry is set to Cancelled (a later settlement is still recorded).
Processing (paid in full, waiting for confirmations) Processing, with a note. The return page tells the customer the payment was received and is waiting for network confirmation.
Settled Paid, after the amount, currency, store and order ID match the entry. Notes mention a hand-marked or overpaid invoice.
Expired, nothing paid Cancelled
Expired after a partial or late payment Pending, with a note asking you to review the invoice. Never marked Paid automatically.
Invalid Failed

Repeated or delayed webhooks

Each delivery is handled once; a redelivery of a handled delivery is acknowledged without a second read-back. If the read-back fails, the add-on answers 503 so BTCPay Server delivers the webhook again, and the five-minute status check also picks the payment up.

An entry paid through BTCPay Server: the box with the status, amount, invoice, order ID, BTCPay Server status, payment method and payment ID, the refund link for the customer, the Refresh status button and the refund form
The entry: status, invoice and payment details read back from your server, and a refund link for the customer.

BTCPay Server refunds are pull payments: you create a refund link, the customer opens it and enters their own address, and you approve and send the payout in BTCPay Server. On a paid entry, enter the amount in the BTCPay Server box and click Create refund link. The add-on reads the invoice back first, then asks your server for a refund in the invoice currency. The link appears in the box for you to copy and send to the customer.

  • Full or partial: several links are possible, up to the paid amount minus what is refunded or still open on other links.
  • The refund is recorded on the entry only when BTCPay Server shows the payout as Completed, once per payout. The entry becomes Refunded when the whole amount is paid out.
  • A link archived in BTCPay Server is closed on the entry with a note.
  • If your server does not answer the refund request, the add-on blocks new links for an hour so you can check Pull Payments in BTCPay Server first.

Developer hooks

  • gravityextra_btcpay_request_metadata: change the description and customer fields of the invoice (the amount, currency and order ID are always set by the add-on).
  • gravityextra_btcpay_currencies: limit the currencies that can be invoiced.
  • gravityextra_btcpay_max_minor: lower the largest payment (in minor units).
  • gravityextra_btcpay_rate_limit and gravityextra_btcpay_payments_per_hour: per-visitor limits and the hourly cap.
  • gravityextra_btcpay_allow_private_server: allow a BTCPay Server on a private network address.
  • gravityextra_btcpay_notify_url: change the webhook address shown in the settings.
// Put the service date in the invoice description of one form (ID 7).
// The amount, currency, order ID and checkout options cannot be changed here.
add_filter( 'gravityextra_btcpay_request_metadata', function ( $meta, $feed, $entry, $form ) {
    if ( 7 !== (int) rgar( $form, 'id' ) ) {
        return $meta;
    }
    $meta['itemDesc'] = 'Bike service on ' . rgar( $entry, '8' ) . ' / booking ' . rgar( $entry, 'id' );
    return $meta;
}, 10, 4 );

// A BTCPay Server on your own network (for example 192.168.1.20): allow private addresses.
add_filter( 'gravityextra_btcpay_allow_private_server', '__return_true' );

Testing

Use a store on a testnet or regtest BTCPay Server for Test mode. Submit your form, pay the invoice with a test wallet and check that the entry becomes Paid with the invoice ID and a test payment note. Try a payment that waits for confirmations and an invoice that expires, then create a small refund link. In Store Settings → Webhooks you can see every delivery and redeliver one: a redelivery never completes a payment twice.

Going live

Enter the server address, store ID, API key and webhook secret of your production store in the Live fields, switch the mode to Live and save. Create the webhook in the production store too. Each entry remembers the mode, server and store it was created with, so older test entries still read back from the test server.

Troubleshooting

  • “No rate available” when the payment starts: the rate source of your store has no rate for the form currency. Pick another source in Store Settings → Rates.
  • The address is refused as private: the host resolves to a private network address. Use the public https address, or allow it with the filter above if the site and the server share a network.
  • No checkout link on the configured server: check that your reverse proxy forwards the original host and https scheme to BTCPay Server.
  • Webhooks show 401 in BTCPay Server: the webhook secret in the add-on does not match the webhook. Copy it again.
  • Entries stay Processing: the invoice is waiting for confirmations, or no payment arrived. Click Refresh status on the entry.

Uninstall

Deleting the plugin removes its settings (including the encrypted keys and secrets), schedules, locks and counters. Invoices, payments and pull payments on your BTCPay Server stay as they are.

Still need help?

Our support team answers tickets every day, usually within a few hours.

0
0
Your Cart
Your cart is emptyReturn to Shop
🔥 FREQUENTLY BOUGHT TOGETHER
Complete Combo & Save 40%!
ITEM IN YOUR CART
Gravity Forms Klaviyo Add-on
$39.00/yr
+
🎁 RECOMMENDED ADD-ON SAVE 40% OFF
Original Price: $39.00/yr
Bundle Special Price: $23.40/yr