﻿# Snap Finance Checkout (WooCommerce)

![PHP](https://img.shields.io/badge/PHP-7.4%2B-777BB4?logo=php&logoColor=white)
![Laravel](https://img.shields.io/badge/Laravel-N%2FA%20(WooCommerce%20plugin)-FF2D20?logo=laravel&logoColor=white)
![Node](https://img.shields.io/badge/Node-optional%20tooling-339933?logo=node.js&logoColor=white)
![License](https://img.shields.io/badge/License-GPL--2.0%2B-blue)

Snap Finance Checkout is a WooCommerce payment gateway that lets shoppers apply for Snap lease-to-own financing at checkout. Merchants configure Client ID and Secret per environment (Sandbox, Production, and optional Dev/QA). Checkout and order-pay flows pre-validate billing and shipping addresses so unsupported countries or states are blocked before a Snap payment request is sent.

The plugin runs as a WordPress/WooCommerce extension (not a Laravel Bref Lambda service). Storefront and admin assets are enqueued from the plugin; Snap SDK launch happens on the order-pay page after address validation. Marketplace packaging also keeps the classic WordPress.org text in `README.txt`.

## Cursor init

Cursor agents use this section to select the php-laravel-serverless review/upgrade asset set (closest supported PHP project-type for this WooCommerce plugin; Laravel + Bref + Serverless are not runtime dependencies).

- **project-type:** php-laravel-serverless
- **liquibase:** no

## Table of content

- [Cursor init](#cursor-init)
- [Prerequisites](#prerequisites)
- [Technology stack table](#technology-stack-table)
- [Address validation](#address-validation)
- [Checkout & order-pay flow](#checkout--order-pay-flow)
- [Project structure](#project-structure)
- [Configuration](#configuration)
- [Backend integration](#backend-integration)
- [Starting service locally](#starting-service-locally)
- [Environments](#environments)

## Prerequisites

- PHP 7.4+ (matching the WordPress host)
- WordPress with WooCommerce active
- Composer (dev tooling / PHPUnit / PHPCS)
- Node.js and npm (optional; not required to run the plugin)
- Network access to Snap Auth and Platform APIs
- Merchant Snap partner credentials (Client ID / Secret)

```bash
php -v
composer -V
node -v
npm -v
serverless --version
```

## Technology stack table

| Technology | Version / Details | Purpose |
| --- | --- | --- |
| PHP | 7.4+ | Plugin runtime |
| WordPress | Latest supported | Host CMS |
| WooCommerce | Latest supported | Checkout, orders, payment gateway API |
| Snap Platform / Auth APIs | Environment-specific | Token, application, SDK |
| jQuery (WP / checkout) | Bundled with WordPress | Checkout UX and Snap application scripts |
| Composer | require-dev | PHPCS (`woocommerce/woocommerce-sniffs` ^2.0.0 → WPCS 3.4.1), PHPUnit, Brain Monkey |
| PHPUnit | ^9.6 (dev) | Unit tests with Brain Monkey WordPress mocks; 80% line coverage gate on `includes/` |
| Brain Monkey | ^2.6 (dev) | Mock WordPress core functions without a full WP install |
| Node.js | Optional | Local tooling only |
| Laravel / Bref / Serverless | N/A | Declared project-type compatibility only; not used by this plugin |

## Address validation

Before Snap payment launch, billing and shipping addresses are validated in PHP (`validate_fields`, `process_payment`, order-pay) and in checkout / Snap application JavaScript.

| Failure code | Typical cause | Customer outcome |
| --- | --- | --- |
| `customerInformation_billingAddress_country_invalid` | Billing country not US | Clear error; payment blocked |
| `customerInformation_billingAddress_state_invalid` | Blank or invalid US state | Clear error; payment blocked |
| `customerInformation_billingAddress_state_not_support` | US state not supported by Snap | Clear error; payment blocked |
| `cartInformation_shippingAddress_state_invalid` | Invalid shipping state | Clear error; payment blocked |

Validation failures are logged via `add_log_message()` for monitoring. Snap Finance is US-only for billing/shipping countries.

## Checkout & order-pay flow

- Shopper selects Snap Finance on classic checkout (including Elementor WooCommerce checkout); place-order runs gateway `validate_fields()` including address checks.
- Classic checkout enqueues `checkoutButtonUrl` from gateway settings so the Pay with Snap image applies only when configured; otherwise the theme Place order button stays visible (avoids transparent text on Elementor).
- On success, `process_payment()` re-validates order addresses, then redirects to order-pay (or checkout modal when cart subtotal is under the Snap minimum).
- Order-pay loads Snap SDK scripts only when addresses pass; application JS re-checks original billing fields before `launchCheckout`.

## Project structure

```text
woocommerce-checkout-plugin/
├── assets/
│   ├── css/
│   │   └── snap-finance-checkout.css
│   ├── js/
│   │   ├── snap-finance-application.js
│   │   ├── snap-finance-checkout.js
│   │   ├── snap-finance-checkout-admin.js
│   │   └── snap-finance-front-checkout.js
│   └── images/
├── includes/
│   ├── class-snap-address-validator.php
│   ├── class-snap-blocks.php
│   └── class-snap-connect.php
├── tests/
│   ├── bootstrap.php
│   ├── TestCase.php
│   ├── assert-min-coverage.php
│   ├── AddressValidatorTest.php
│   ├── PaymentAddressGateTest.php
│   ├── ConnectModeTest.php
│   ├── ConnectAjaxTest.php
│   └── ConnectCoverageTest.php
├── templates/
├── snap-finance-checkout.php
├── snap-finance-functions.php
├── snap-finance-payment-class.php
├── snap-finance-wc-order.php
├── config.php
├── composer.json
├── phpunit.xml.dist
├── phpcs.xml
├── README.md
└── README.txt
```

## Configuration

| Location | Purpose |
| --- | --- |
| `config.php` / `snap-finance-checkout.php` | Environment Auth/Audience/SDK URL constants, plugin bootstrap |
| WooCommerce gateway settings (`woocommerce_snap_finance_settings`) | Enable flag, environment, Client ID/Secret, button assets |
| `phpcs.xml` / `composer.json` | Coding standards and test tooling |
| `README.txt` | WordPress.org marketplace plugin readme |

Deployed secrets are merchant-entered and stored in the WooCommerce gateway options for the store—not AWS Secrets Manager.

| Configuration key | Purpose |
| --- | --- |
| `woocommerce_snap_finance_settings` | Gateway option bag (mode, client id/secret per env, UI assets) |
| `Sandbox_*` / `Live_*` / `Dev_*` / `Qa_*` | Environment-specific Snap Auth/Audience/SDK endpoints in `config.php` |
| `SNAP_Finance_*` / `SNAP_Finance_*_CONNECT_*` | Snap Connect OAuth client, token/verify timeouts, popup UI, and per-env authorize/token URLs in `config.php` |
| `WOOCOMMERCE_GATEWAY_SNAP_FINANCE_VERSION` | Asset version constant |
| `SNAP_ENV` | Optional host flag to expose Dev/QA modes in gateway settings |

## Backend integration

| Integration | Usage |
| --- | --- |
| WooCommerce Payment Gateway API | `WC_snap_finance_Gateway` registers Snap as a payment method |
| Snap Auth (client_credentials) | Issues access token used by Snap SDK |
| WordPress admin AJAX | Complete payment, status updates, notes after Snap application events |
| Snap Checkout SDK | Order-pay `snap.checkoutButton` / `launchCheckout` |
| Address validator | Shared PHP + localized JS config for US country/state rules |

Address validation orchestration lives in `includes/class-snap-address-validator.php`; gateway hooks in `snap-finance-payment-class.php`; order-pay enqueue in `snap-finance-functions.php`.

## Starting service locally

### 1. Clone and enter the project

```bash
git clone <repository-url> woocommerce-checkout-plugin
cd woocommerce-checkout-plugin
```

Place the folder under `<wordpress-root>/wp-content/plugins/` (or symlink that path to this repo) and activate **Snap Finance** in WordPress Admin → Plugins.

### 2. Install dependencies

```bash
composer install
npm install
```

(`npm install` is optional; no Mix/Webpack build is required for runtime assets.)

### 3. Configure environment

- Activate WooCommerce and this plugin.
- Open WooCommerce → Settings → Payments → Snap Finance.
- Enable the gateway, choose environment, and enter Client ID / Secret.
- Use a US billing address when testing Snap checkout.

### 4. Build admin assets

No Mix/Webpack build is required. Edit `assets/js/snap-finance-*.js` and related CSS directly; WordPress enqueues them from the plugin directory.

### 5. Local development notes

- Run `composer test` for unit tests under `tests/` (Brain Monkey mocks WordPress — no full WP install required). Targets `includes/` (`Snap_Finance_Address_Validator`, `Snap_Finance_Connect`).
- Run `composer test:coverage` with **pcov** or **xdebug** enabled to generate clover coverage; `tests/assert-min-coverage.php` enforces the **80%** line-coverage Definition of Done on `includes/` (excludes `class-snap-blocks.php`, which depends on WooCommerce Blocks).
- Run PHPCS via Composer sniffs when changing PHP.
- Prefer US addresses; non-US countries should show a customer-facing error and must not launch Snap.
- Clear Snap token transients after credential changes if tokens were cached.

## Environments

Deployed plugin behavior follows the WordPress site URL and the Snap endpoints selected by `snap_finance_mode` / constants in `config.php`.

### Local

| Environment | Base URL |
| --- | --- |
| Local WordPress | `http://localhost/` (or your local vhost) |

### Lower environments

| Environment | Base URL |
| --- | --- |
| Snap developer docs | `https://developer.snapfinance.com/` |
| Snap Auth / Platform | See `Sandbox_*`, `Live_*`, `Dev_*`, `Qa_*` in `config.php` |

---
Last updated: August 2026
Maintained by: Merchants ART / Snap Finance Checkout
