=== GoBTC Pay for WooCommerce ===
Contributors: gobtcpay
Tags: bitcoin, btc, payment gateway, cryptocurrency, payments
Requires at least: 6.0
Tested up to: 7.1
Requires PHP: 8.1
WC requires at least: 8.0
WC tested up to: 11.1.2
Stable tag: 1.1.4
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Accept Bitcoin payments in your WooCommerce store via a hosted GoBTC Pay checkout.

== Description ==

GoBTC Pay for WooCommerce adds Bitcoin as a payment method to your store. The
customer is sent to a hosted checkout operated by GoBTC Pay, pays there, and —
if your store is served over https — comes back to its usual order-received
page. Your store never handles
private keys, wallet software or on-chain transactions.

The plugin keeps the order in step with the payment through two independent
channels: it polls the payment status on a schedule, and it accepts signed
webhook deliveries from GoBTC Pay. The two overlap almost everywhere, so a
single missed poll or a single undelivered webhook does not strand a paid
order. They are not interchangeable, though: once an order's payment window and
its grace period have both run out, polling for that order stops, and a payment
that arrives after that reaches the store only as a webhook. Keeping the webhook
endpoint reachable is therefore not optional.

= Two payment routes, and they do not behave the same =

This is the part worth understanding before you install, because it decides
when your goods are released.

**Paid from a wallet inside the GoBTC Pay ecosystem (instant).** The payment
reports as paid in one step. The order is marked paid and moves straight to a
state that allows fulfilment — Processing, or Completed for an order that needs
no shipping. There is no waiting period. The plugin keeps polling in the
background until the on-chain settlement time appears, but the order is already
paid and the merchant is not asked to wait for it.

**Paid from an ordinary Bitcoin wallet (external).** The transfer is first seen
in the mempool, and the order is held On hold while it waits for network
confirmation. Only once the payment is confirmed on-chain does the order move
to a state that allows fulfilment. This usually takes about 10 to 30 minutes,
but it can take considerably longer when the Bitcoin network is congested.
Confirmation time is a property of the network: neither the plugin nor your
store can influence it.

Both routes end with a paid order. The difference is the path the order takes
and how long it takes to get there, so an On-hold order from an external
payment is a normal, expected state and not a fault.

= Late payments =

If the payment window closes before the customer pays, the order is held rather
than cancelled, and the plugin keeps watching it for a configurable grace period
(12 hours by default). A payment that arrives inside that window still pays the
order.

What happens after the grace period. If nothing arrives before it ends, the
order is cancelled: WooCommerce restores the stock and sends its own
cancellation e-mail. In most cases that is the end of it, because the payment
is cancelled on the GoBTC Pay side at the same time. Occasionally the money is
already on its way and that cancellation does not go through. The payment is
then applied after all: the order returns to Processing, the stock is reduced
again, which leaves the count correct because cancelling had returned it, and
the order gets a note saying it was cancelled and paid after all. The
cancellation e-mail your customer has already received is not retracted, so
tell them the order is going ahead. Treat it as any other paid order and ship
it.

= What the plugin does not do =

* It does not process refunds. Refunds are handled outside the plugin.
* It does not support subscriptions or pre-orders.
* It does not store card details or private keys, because it never sees any.

= External service disclosure =

This plugin is a client for a third-party service and does not work without it.

See "External service" below for the service, its endpoints and its legal
terms. This subsection covers the one thing that section does not: exactly what
leaves your store, and the one configuration that can cost you real money.

**Endpoints contacted by your server:** the API base URL you configure in the
plugin settings — `https://api.gobtcpay.com/public/api/v1.2` for production, or
`https://pay.dev.gobtcpay.com/public/api/v1.2` for the separate non-production
contour operated by GoBTC Pay. **That contour runs on Bitcoin mainnet: payments
made against it move real BTC.** It is not a sandbox and there is no test
network behind it.

**What your server sends to GoBTC Pay:**

* When an order is placed: the order total, the order currency, and a reference
  string built from a random identifier of this installation, the WooCommerce
  order ID, currency and total (for example
  `wc-a1b2c3d4-order-1234-USD-4999`). The installation identifier is a random
  value and is not derived from your site address. No customer name, e-mail
  address, postal address or cart contents are sent, and the customer's IP
  address is not sent.
* Afterwards, to follow the payment: the identifier of the payment that GoBTC
  Pay returned.
* When an order is cancelled or its total changes: the identifier of the
  payment that is no longer valid.
* To verify your credentials: your secret API key, so the platform can confirm
  it is usable. This runs when you save the settings, and is retried in the
  background — for up to about a day — if the platform could not be reached.
* When you press the webhook test button: a request to deliver a test webhook to
  your store.

**What GoBTC Pay sends back to your server:** the payment's status, amount,
currency, identifiers, timestamps and, where present, its on-chain transactions.
Webhook deliveries are signed and their signature is verified before anything is
applied to an order.

**What the customer's browser sends:** the customer is redirected to the GoBTC
Pay hosted checkout, so their browser contacts GoBTC Pay directly and that
service sees whatever a website normally sees about a visitor. The redirect
carries the two addresses the customer is returned to on your store — the
order-received page and the pay-again page.

**Terms of service:** https://gobtcpay.com/terms
**Privacy policy:** https://gobtcpay.com/privacy-policy

== External service ==

This plugin connects your WooCommerce store to GoBTC Pay, a Bitcoin payment
service operated by GoMining. The plugin does not process payments itself:
it creates a payment through the GoBTC Pay merchant API and redirects the
customer to the GoBTC Pay hosted checkout page to complete it.

The service is contacted in the following cases:

* when a customer places an order and selects GoBTC Pay as the payment
  method, to create the payment and obtain the checkout URL
* periodically after that, to read the current payment status until the
  payment reaches a final state
* when the plugin validates your API key, sends a test webhook, or cancels
  a payment from the WooCommerce admin

The customer is redirected to the hosted checkout page at
https://pay.gobtcpay.com. Whether they are sent back afterwards depends on your
store: a return address is only handed to the hosted checkout when the store is
served over https, and without one the customer stays on the checkout page after
paying — see "Installation" for the requirement. The payment itself is
unaffected either way: the plugin reads the payment status from the service on
its own schedule, so an order still reaches its final state whether or not the
customer comes back.

The data sent to the service for each payment is the order amount, the
order currency, and an order reference generated by the plugin. Your secret
API key is sent as an authorization header and is never exposed to the
customer's browser.

Service provider: GoMining (GoBTC Pay)
Merchant API: the GoBTC Pay merchant API, at the base URL configured in the
plugin settings
Hosted checkout: https://pay.gobtcpay.com
Terms of Service: https://gobtcpay.com/terms
Privacy Policy: https://gobtcpay.com/privacy-policy

== Installation ==

1. Install and activate the plugin. WooCommerce must be installed and active.
2. Go to WooCommerce → Settings → Payments → GoBTC Pay.
3. Enable the payment method and fill in the three required fields:
   * **Secret API key** — the `sk_live_…` key from your GoBTC Pay dashboard. A
     publishable key (`pk_live_…`) is rejected outright when you save. A key
     restricted to a single store is rejected too, provided the platform answers
     the check; if it cannot be reached, the settings are saved with the key
     unverified and the check is retried in the background.
   * **Webhook signing secret** — the `whsec_…` secret of the webhook endpoint
     you create in the GoBTC Pay dashboard.
   * **API base URL** — the production URL, or the non-production one described
     under "External service disclosure" above. The keys carry no environment
     marker, so the environment is chosen here and nowhere else.
4. Serve your store over https. A return address that is not https is not
   accepted by the hosted checkout, so customers who pay are not sent back to
   your store automatically. Payment status still syncs, and orders are still
   completed.
5. Copy the webhook URL shown on the settings page and register it as a webhook
   endpoint in your GoBTC Pay dashboard.
6. Use the webhook test button on the settings page to confirm that deliveries
   reach your store.

Saved secrets are never displayed back on the settings page: the field renders
empty, and leaving it empty when you save means "keep the current value".

== Frequently Asked Questions ==

= Do I need a Bitcoin wallet or a node to use this? =

No. The plugin talks to the GoBTC Pay API and the customer pays on the GoBTC Pay
hosted checkout. Your store never holds keys or funds.

= Why is an order stuck On hold? =

Most likely it was paid from an ordinary Bitcoin wallet and is waiting for
network confirmation — usually about 10 to 30 minutes. See "Two payment routes"
above. An order can also be On hold because the payment window closed and the
plugin is waiting out the grace period in case the money still arrives.

= Why did another order go to Processing straight away? =

It was paid from a wallet inside the GoBTC Pay ecosystem. That route reports the
payment in one step, so the order is completed immediately and no confirmation
wait applies.

= Can I refund through the plugin? =

No. The plugin declares support for products only; refunds are not part of it.

= What happens if my webhook endpoint is unreachable? =

For an order that is still being watched, nothing is lost: the plugin also polls
the payment status, so the order reaches its final state anyway.

It does matter for one case. Once an order's payment window and its grace period
have both expired, the order is cancelled and polling for it stops — a payment
that arrives after that point can only reach the store as a webhook. With the
endpoint unreachable, such an order stays cancelled while the customer believes
they have paid.

That is why, when payments are being created but no webhook has arrived for a
while, the plugin raises an admin notice pointing at the usual causes: a changed
URL, a firewall or security plugin blocking the request, or a signing secret that
no longer matches. It is shown on WooCommerce's own screens, to users who can
manage WooCommerce, and it is worth acting on.

= Can I point the plugin at a non-production environment? =

Yes. GoBTC Pay runs a separate non-production contour; set the API base URL to
it and use the credentials issued for that contour.

**It is not a sandbox.** That contour settles on Bitcoin mainnet, so any payment
you make against it spends real BTC and cannot be reversed. Treat an order
placed there exactly as you would treat one in production.

= I copied my store to a staging or test site. What must I do? =

**Never let a copy run with the live secret key.** Before the copy is first
opened, not after, do one of two things on it: deactivate this plugin, or save a
separate key over the live one. Emptying the "Secret API key" field does **not**
remove the stored key — a blank field means "keep the current value" — and
disabling the payment method does not stop the plugin talking to GoBTC Pay
either. The key is not read-only: a copy that has it can cancel your production
customers' payments. A copy carries the same orders and the same
payment identifiers, and the plugin asks the service to cancel a payment
whenever its order is cancelled or has outgrown it — so cancelling an order on
the copy, or letting it expire there, cancels the real payment of a real
customer. Nothing on the copy looks wrong while this happens; the damage shows
up in the live store.

Second, and only once the key is dealt with: clear the plugin's site identifier
on the copy, the `gobtc_pay_site_id` option. It is what keeps this store's
payment identifiers apart from your other stores', and a copy starts out
carrying the original's. Deleting the option is enough — the plugin creates a
new one by itself. The current value is shown as "Installation identifier" at
the bottom of the payment method's settings screen, which is how you can tell
the copy from the original once you have done this.

= I turned the payment method off. Has the plugin stopped? =

No. Turning the payment method off removes it from checkout, so no new payment
is created. It does not stop the plugin working on payments that already exist:
it keeps polling them, keeps accepting webhook deliveries, keeps applying
payment results to orders, and keeps cancelling the payment of an order that is
cancelled or whose total has changed. That is deliberate — an order whose
customer has already sent bitcoin still has to reach the right state.

Deactivating the plugin is the only thing that stops all of it.

= Which WooCommerce checkout does it work with? =

Both. The classic shortcode checkout and the Cart & Checkout Blocks checkout are
supported.

== Changelog ==

= 1.1.4 =
* A cancelled order that is paid after all now gets a note saying it was cancelled and paid, and can be shipped as usual; it is no longer also marked as needing to be settled by hand.

= 1.1.3 =
* Packaging and metadata only: development-only files are no longer shipped in the archive. The plugin itself behaves exactly as 1.1.2 did.

= 1.1.2 =
* The plugin's admin notices are now limited to the people who can act on them
  and to the screens where they would act — Plugins, the Dashboard and
  WooCommerce's own screens — rather than every screen in wp-admin. Which of them
  a notice uses follows what it is about: one about the installation (WooCommerce
  missing, a damaged package, this plugin active twice) needs the capability to
  install plugins; one about the running shop (a silent webhook channel, orders
  that need attention) needs the capability to manage WooCommerce and is confined
  to WooCommerce's own screens. A configuration problem that stops the store
  taking payments at all is the exception: it is still shown on any wp-admin
  screen.

= 1.1.1 =
* Packaging and metadata only: the distributed archive now ships the Composer
  manifest alongside the prefixed dependencies it describes, and the tested-up-to
  version is recorded in the format the plugin directory expects. The plugin
  itself behaves exactly as 1.1.0 did.

= 1.1.0 =
* Payment identifiers sent to GoBTC Pay now carry a short identifier of this
  installation and begin with `wc-`, for example
  `wc-a1b2c3d4-order-1234-USD-4999`. Two stores of one merchant that reached
  the same order number for the same amount used to produce the same
  identifier, and the platform treats one identifier as one payment — so the
  second store was handed the first store's payment. Payments created before
  this update keep working unchanged.
* The payment method's settings screen now shows this installation's identifier,
  read-only, so that a merchant running several stores on one GoBTC Pay account
  can tell which payment references belong to which store.
* The default "API base URL" now points at `api.gobtcpay.com`, the merchant
  API's own host. Stores that already have a value saved keep it — this changes
  only what a fresh install starts with.
* The plugin folder is now `gobtc-pay-for-woocommerce`. Nothing a store has
  saved moves with it: the settings, the payment method and the payment data on
  existing orders are keyed by identifiers that did not change.
* An older copy of the plugin left active alongside this one is now reported:
  the plugin names the folder to deactivate and delete, instead of the stale
  copy sitting there unnoticed.

= 1.0.0 =
* First public release.
* Bitcoin payment method for WooCommerce backed by the GoBTC Pay hosted
  checkout.
* Support for both the classic shortcode checkout and the Cart & Checkout Blocks
  checkout.
* Order status kept in step with the payment through two independent channels:
  scheduled polling and signed webhooks.
* Immediate completion for payments made from a wallet inside the GoBTC Pay
  ecosystem; confirmation wait for payments made from an ordinary Bitcoin
  wallet.
* Configurable grace period (12 hours by default) during which a late payment
  still pays an expired order.
* Settings-time validation of the merchant key and a webhook delivery test.
* Declared compatible with WooCommerce High-Performance Order Storage (HPOS).

== Upgrade Notice ==

= 1.1.0 =
Installed by hand from a release zip before? The folder is renamed in this
version, so the old one stays behind as a separate, still-active plugin.
Deactivate and delete it — the new copy will tell you if you forget. Your
settings and existing orders are unaffected.

= 1.0.0 =
First public release.
