# WooCommerce plugin

**payitgo for WooCommerce** adds crypto to a WooCommerce shop's checkout. The
customer chooses it, pays on payitgo's [hosted checkout](/docs/checkout), and
comes back to the shop; the order is marked paid once the payment is final.
No code to write.

| | |
|---|---|
| Download | The zip of the [latest release](https://github.com/payitgo/woocommerce/releases/latest) |
| Source | [github.com/payitgo/woocommerce](https://github.com/payitgo/woocommerce) |
| Needs | WordPress 6.3+, WooCommerce 8.0+, PHP 7.4+ |
| Checkout | The block checkout and the classic checkout |
| Orders | WooCommerce's order tables (HPOS) or posts |
| Shop currency | Any: prices are converted at the rate of the moment ([prices in other currencies](/docs/payments#prices-in-other-currencies)) |

## Install

1. Download `payitgo-for-woocommerce-X.Y.Z.zip` from the latest release, and
   upload it in WordPress (Plugins > Add New > Upload Plugin). Activate it.
2. Copy a secret key from your dashboard (Developers > API keys), one with
   full access (the plugin creates payments; a read-only key cannot): a test
   key to try it out, a live key for real payments. Several shops on one
   account: give each the key of its own [store](#several-shops-on-one-account).
3. In WooCommerce > Settings > Payments > **payitgo (crypto)**, paste the key
   and enable it.

Nothing else. When you save the settings, the plugin asks payitgo whether
the key is a test or a live key (`GET /v1/webhook`'s `livemode`) and reads
your webhook's signing secret with it; an unknown key is reported ("payitgo
does not know this secret API key: copy it again from your payitgo
dashboard"). Each payment then tells the shop how it went.

## Settings

| Setting | Default | |
|---|---|---|
| Title, Description | "Crypto (USDT, BTC, ETH and more)" | What customers see at checkout |
| Secret API key | | A test key to try it out, a live key for real payments. Its mode is the plugin's: a test key's payments are [simulated](/docs/testing) |
| Signing secret | (read with the key) | Pin one only if you must; otherwise the plugin reads it, and reads it again once if you [roll it](/docs/webhooks#the-signing-secret) |
| API address | `https://api.payitgo.co` | |
| Debug log | off | WooCommerce > Status > Logs, source `payitgo`. Errors are always logged |

## What it sends

When the customer places the order, the plugin [creates a payment](/docs/payments#create-a-payment):

| Field | From the order |
|---|---|
| `order_id` | The order number, as it is: `1234` |
| `amount_usd` | The total, for a shop in US dollars |
| `price_amount`, `price_currency` | The total and the shop's currency, for any other shop |
| `description` | The items: `2 x Acme T-shirt, Mug` |
| `customer_email` | The billing email |
| `success_url`, `cancel_url` | The order-received page, and WooCommerce's cancel link |
| `webhook_url` | The shop's notification address, `https://<shop>/wc-api/payitgo/`, when the shop is on https |
| `metadata` | `wc_order_id` (how the plugin finds the order), `wc_order_number`, `shop` |

The customer is then sent to the payment's `checkout_url`, where they choose
the coin. Paying an order again (after its payment expired) makes a new
payment; while one is open, the customer gets that one.

## Several shops on one account

Order ids are [unique per store](/docs/payments#safe-retries). Create a
[store](/docs/account#stores) for each shop (Stores in the dashboard) and give
each shop the key of its own store: two shops can then both have an order
`1234`. Shops that share one key would be given each other's open payment for
the same order number: the plugin refuses such a payment, and logs why.

## How orders follow the payment

The plugin verifies each [notification](/docs/webhooks#the-notification),
ignores one it handled already, one of the other mode, or one for a payment
the order did not make, and moves the order by the payment's `status`:

| Payment | Order |
|---|---|
| `detecting` | On hold: the money arrived, confirmations are pending |
| `confirmed` | Paid (processing, or completed for virtual goods), with the transaction id. On hold instead when the payment was for another amount than the order's total |
| `partially_paid` | A note: the customer can still send the rest |
| `underpaid` | On hold, with what arrived: refund the customer or agree on the rest |
| `expired`, `failed` | Failed: the customer can pay again from their account |

A deposit in another coin (`payment.wrong_asset`), or after the payment
closed (`payment.late_deposit`), adds a note. The order-received page also
reads the payment, so a shop that notifications cannot reach (not on https,
or behind a firewall) learns the outcome when the customer comes back.

## Test it

With a test key, the checkout page lets you choose how the payment goes:
place an order, choose a coin, and play `confirmed`: the order goes on hold,
then to processing, within seconds. Play `expired` to see an order fail, then
pay it again from the customer's account.

## Refunds

Not from WooCommerce yet: send the coins back from your wallet, then mark the
order refunded.
