### Moneymotion API Key Example Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/configuration.md Examples of valid API keys for moneymotion. Use mk_live_ for production and mk_test_ for testing. ```text mk_live_1234567890abcdef mk_test_abcdef1234567890 ``` -------------------------------- ### Example Line Item Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/types.md An example of how to structure a line item array for use with the createCheckoutSession function. ```php $lineItems = [ [ 'name' => 'Membership', 'description' => 'Annual membership renewal', 'pricePerItemInCents' => 9999, // $99.99 'quantity' => 1 ] ]; ``` -------------------------------- ### Example Metadata Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/types.md An example of metadata array. This data is converted to an object before being sent to the API. ```php $metadata = [ 'invoice_id' => 42, 'transaction_id' => 1, 'gateway_id' => 5 ]; ``` -------------------------------- ### Example Gateway Settings Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/types.md An example of the JSON structure for moneymotion gateway settings. This includes placeholder values for the API key and webhook secret. ```json { "api_key": "mk_live_...", "webhook_secret": "whsk_..." } ``` -------------------------------- ### Example Callback URLs Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/types.md An example of callback URLs, including placeholders for transaction ID and CSRF token. Ensure all URLs are HTTPS. ```php $urls = [ 'success' => 'https://community.com/moneymotion/webhook/success?t=42&csrf_token=abc123...', 'cancel' => 'https://community.com/moneymotion/webhook/cancel?t=42&csrf_token=def456...', 'failure' => 'https://community.com/moneymotion/webhook/failure?t=42&csrf_token=ghi789...' ]; ``` -------------------------------- ### Payment Initiation Log Messages Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/errors.md Examples of log messages generated when a payment attempt starts and a checkout session is created. These logs track the initial steps of a transaction. ```log moneymotion: payment attempt started - transaction_id: 1, invoice_id: 42, member_id: 5, amount: 29.99 USD ``` ```log moneymotion: checkout session created - session_id: sess_..., transaction_id: 1, amount_cents: 2999 ``` -------------------------------- ### Example RPC Request for Checkout Session Creation Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/types.md An example of a JSON payload for creating a checkout session via the moneymotion API. It includes details about the transaction, user info, and line items. ```json { "_tag": "Request", "id": "0", "tag": "CheckoutSessionsCreateCheckoutSession", "payload": { "description": "Invoice #42", "urls": { "success": "https://...", "cancel": "https://...", "failure": "https://..." }, "userInfo": {"email": "customer@example.com"}, "lineItems": [ { "name": "Membership", "description": "Payment for Invoice #42", "pricePerItemInCents": 2999, "quantity": 1 } ], "metadata": {"invoice_id": 42, "transaction_id": 1, "gateway_id": 5} }, "headers": [] } ``` -------------------------------- ### Failure Return URL Example Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/endpoints.md Example URL for handling failed payments on Moneymotion checkout. Includes transaction ID and CSRF token. ```URL https://community.com/moneymotion/webhook/failure?t=42&csrf_token=abc123def456... ``` -------------------------------- ### Moneymotion Webhook Secret Example Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/configuration.md Example of a webhook signing secret. This is used to verify the authenticity of incoming webhook payloads. ```text whsk_1234567890abcdefghijklmnopqrstuvwxyz ``` -------------------------------- ### cURL Example for Webhook POST Request Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/endpoints.md Demonstrates how to send a POST request to the moneymotion webhook endpoint using cURL, including necessary headers and a sample JSON payload. ```bash curl -X POST https://community.com/moneymotion/webhook \ -H "Content-Type: application/json" \ -H "X-Webhook-Signature: dGVzdA==" \ -d '{ "event": "checkout_session:complete", "checkoutSession": { "id": "sess_abc123", "totalInCents": 2999 } }' ``` -------------------------------- ### Minor Unit Multiplier Examples Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/types.md Illustrates how minor unit multipliers are applied to different currencies based on their decimal places. Used by _moneymotion::currencyMinorUnitMultiplier() and _gateway::auth(). ```php 1000 JPY = 1000 * 1 cents = 1000 (NOT 100000) 10 USD = 10 * 100 cents = 1000 0.123 BHD = 0.123 * 1000 cents = 123 ``` -------------------------------- ### Example Success Return URL Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/endpoints.md This URL format is used to redirect customers after a successful payment on the moneymotion checkout page. It includes transaction and CSRF tokens for validation. ```url https://community.com/moneymotion/webhook/success?t=42&csrf_token=abc123def456... ``` -------------------------------- ### Webhook Error Response Example Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/endpoints.md A JSON structure for reporting errors encountered during webhook processing. ```json {"error": "Error message"} ``` -------------------------------- ### Webhook Success Response Example Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/endpoints.md A simple JSON response indicating that a webhook notification was processed successfully by the server. ```json {"status": "ok"} ``` -------------------------------- ### Webhook Request Body Example Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/endpoints.md This JSON structure represents the expected format for incoming webhook notifications from the moneymotion payment gateway. ```json { "event": "checkout_session:complete", "timestamp": 1234567890, "checkoutSession": { "id": "sess_...", "totalInCents": 2999, "lineItems": [...], "currency": "USD" } } ``` -------------------------------- ### pluginVersion() Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/api-reference/api-client.md Resolves the installed plugin version from the IPS application row. This method is used to retrieve the plugin's version, which is then included in the User-Agent header for API requests. ```APIDOC ## pluginVersion() ### Description Resolves the installed plugin version from the IPS application row. This method is used to retrieve the plugin's version, which is then included in the User-Agent header for API requests to aid in debugging. ### Signature ```php protected static function pluginVersion() ``` ### Return Type `string` ### Returns Plugin version (e.g. '3.0.18') or `PLUGIN_VERSION_FALLBACK` ('0.0.0') if unreadable. ### Side Effects - Caches result in static `$cachedPluginVersion` to avoid repeated DB reads. - Silently falls back to fallback version if IPS isn't loaded or row is unreadable. ### Usage - Included in `User-Agent` header for API requests to help moneymotion with debugging. - Fallback ensures User-Agent lookup never crashes payment flow. ``` -------------------------------- ### Example Cancel Return URL Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/endpoints.md This URL format is used to redirect customers who cancel their payment on the moneymotion checkout page. It includes transaction and CSRF tokens for validation. ```url https://community.com/moneymotion/webhook/cancel?t=42&csrf_token=abc123def456... ``` -------------------------------- ### Amount Mismatch Response Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/endpoints.md Example of an HTTP 200 OK response for an amount mismatch. The payment is processed as a failure internally, but 200 is sent to acknowledge receipt. ```HTTP HTTP/1.1 200 OK Content-Type: application/json {"status": "ok"} ``` -------------------------------- ### GET /moneymotion/webhook/success Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/endpoints.md Customer is redirected here after a successful payment on the moneymotion checkout. It validates the transaction and CSRF token. ```APIDOC ## GET /moneymotion/webhook/success ### Description Customer is redirected here after a successful payment on the moneymotion checkout. It validates the transaction and CSRF token. ### Method GET ### Endpoint /moneymotion/webhook/success ### Parameters #### Query Parameters - **t** (integer) - Required - Transaction ID. - **csrf_token** (string) - Required - CSRF token for validation. ### Response - HTTP 302 redirect to invoice URL on success. - HTTP 302 redirect to home page on CSRF validation failure. - Flash message: "moneymotion_payment_success" ### Example URL ``` https://community.com/moneymotion/webhook/success?t=42&csrf_token=abc123def456... ``` ``` -------------------------------- ### Throwing LogicException for Invalid Customer Email Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/errors.md This example shows how to throw a LogicException when a customer's email is invalid or missing. This exception is intended for user-facing errors and is caught by the Invision Community checkout flow. ```php throw new \LogicException( \IPS\Member::loggedIn()->language()->addToStack('moneymotion_error_email') ); ``` -------------------------------- ### PHP Plugin Version Resolution Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/api-reference/api-client.md Resolves the installed plugin version from the IPS application row. Caches the result to avoid repeated database reads and falls back to a default version if IPS is not loaded or the row is unreadable. ```php protected static function pluginVersion() ``` -------------------------------- ### Webhook Processing Log Messages Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/errors.md Examples of log messages related to webhook processing, including successful receipt, transaction approval, skipping already completed sessions, and amount mismatches. ```log moneymotion webhook received and verified: checkout_session:complete from IP 203.0.113.50 ``` ```log moneymotion: transaction 1 approved for session sess_... - amount: 2999 cents ``` ```log moneymotion: session sess_... already complete, skipping ``` ```log moneymotion webhook: amount mismatch for session sess_...; expected 2999, got 3000; approval blocked ``` -------------------------------- ### Instantiate API Client with API Key Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/api-reference/api-client.md Create a new API client instance by providing your moneymotion API key directly. The API key will be trimmed upon assignment. ```php $client = new "IPS\moneymotion\Api\Client"('mk_live_...); ``` -------------------------------- ### Instantiate API Client Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/api-reference/api-client.md Create a new API client instance using your moneymotion API key. Ensure the API key is valid. ```php class _Client ``` -------------------------------- ### PHP - Initialize _MoneymotionGatewayStub Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/api-reference/webhook-controller.md Instantiates the _MoneymotionGatewayStub with raw JSON settings. This stub is used when the Gateway hook is not loaded, providing access to gateway settings like API keys and webhook secrets. ```php public function __construct( $settings ) ``` ```php $stub = new _MoneymotionGatewayStub('{"api_key":"mk_...", "webhook_secret":"whsk_..."}'); $settings = json_decode($stub->settings, true); $secret = $settings['webhook_secret']; ``` -------------------------------- ### API Client Constructor Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/api-reference/api-client.md Initializes a new API client instance with a provided API key. The API key is trimmed upon assignment. ```APIDOC ## `__construct($apiKey)` ### Description Creates a new API client instance with the given API key. ### Method `__construct` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **`$apiKey`** (string) - Required - The moneymotion API key (trimmed on assignment). ### Return Type `void` ### Example ```php $client = new IPSmoneymotionApiClient('mk_live_...'); ``` ``` -------------------------------- ### Create API Client from Gateway Settings Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/api-reference/api-client.md Instantiate an API client using the API key stored in the moneymotion gateway settings. This method requires a valid gateway object and will throw an exception if the API key is not configured. ```php $gateway = ".IPS\nexus\Gateway::load('moneymotion'); $client = ".IPS\moneymotion\Api\Client::fromGateway($gateway); ``` -------------------------------- ### API Client Static Factory Method: fromGateway Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/api-reference/api-client.md Creates a new API client instance by loading the API key from gateway settings. Throws an exception if the API key is not configured. ```APIDOC ## `fromGateway($gateway)` ### Description Creates a new API client instance using the API key from gateway settings. ### Method `fromGateway` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **`$gateway`** (`IPSnexusGateway`) - Required - The moneymotion gateway object. ### Return Type `static` (new `_Client` instance) ### Throws - `InvalidArgumentException` if API key is not configured in gateway settings ### Example ```php $gateway = IPSnexusGateway::load('moneymotion'); $client = IPSmoneymotionApiClient::fromGateway($gateway); ``` ``` -------------------------------- ### Stale Timestamp Error Response Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/endpoints.md Example of an HTTP 400 Bad Request response indicating that the webhook timestamp is too old. ```HTTP HTTP/1.1 400 Bad Request Content-Type: application/json {"error": "Webhook timestamp too old"} ``` -------------------------------- ### Public Method: createCheckoutSession Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/api-reference/api-client.md Initiates a new checkout session with the moneymotion backend, returning a session ID for redirecting customers. ```APIDOC ## `createCheckoutSession($description, $urls, $email, $lineItems, $metadata = array(), $currency = 'BRL')` ### Description Creates a new checkout session at the moneymotion backend. ### Method `createCheckoutSession` ### Endpoint Effect RPC protocol (NDJSON format) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **`$description`** (string) - Required - Checkout session description (e.g. "Invoice #123") - **`$urls`** (array) - Required - Callback URLs with keys: `success`, `cancel`, `failure` - **`$email`** (string) - Required - Customer email address - **`$lineItems`** (array) - Required - Array of line item objects (see structure below) - **`$metadata`** (array) - Optional - Custom metadata to associate with the session (Default: `array()`) - **`$currency`** (string) - Optional - ISO 4217 currency code (Default: `'BRL'`) ### Line Item Structure ```php array( 'name' => 'Item Name', 'description' => 'Item description', 'pricePerItemInCents' => 1000, // Price in cents (e.g. 10.00 USD) 'quantity' => 1 ) ``` ### URL Structure ```php array( 'success' => 'https://example.com/moneymotion/webhook/success?...', 'cancel' => 'https://example.com/moneymotion/webhook/cancel?...', 'failure' => 'https://example.com/moneymotion/webhook/failure?...' ) ``` ### Return Type `string` (session ID) ### Returns - moneymotion checkout session ID (used to build checkout URL) ### Throws - `RuntimeException` if RPC response is invalid or missing `checkoutSessionId` - `RuntimeException` if returned session ID is empty ### Example ```php try { $sessionId = $client->createCheckoutSession( 'Invoice #42', [ 'success' => 'https://community.com/moneymotion/webhook/success?t=1&csrf_token=...', 'cancel' => 'https://community.com/moneymotion/webhook/cancel?t=1&csrf_token=...', 'failure' => 'https://community.com/moneymotion/webhook/failure?t=1&csrf_token=...' ], 'customer@example.com', [ [ 'name' => 'Membership', 'description' => 'Payment for Invoice #42', 'pricePerItemInCents' => 2999, // $29.99 'quantity' => 1 ] ], ['invoice_id' => 42, 'transaction_id' => 1], 'USD' ); // Redirect customer to checkout header("Location: https://moneymotion.io/checkout/{$sessionId}"); } catch (RuntimeException $e) { echo "Failed to create checkout: " . $e->getMessage(); } ``` ``` -------------------------------- ### GET /moneymotion/webhook/cancel Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/endpoints.md Customer is redirected here if they cancel the payment on the moneymotion checkout. It validates the CSRF token and updates the transaction status. ```APIDOC ## GET /moneymotion/webhook/cancel ### Description Customer is redirected here if they cancel the payment on the moneymotion checkout. It validates the CSRF token and updates the transaction status. ### Method GET ### Endpoint /moneymotion/webhook/cancel ### Parameters #### Query Parameters - **t** (integer) - Required - Transaction ID. - **csrf_token** (string) - Required - CSRF token for validation. ### Response - HTTP 302 redirect to invoice checkout URL. - Flash message: "moneymotion_payment_cancelled" ### Side Effects - Transaction marked as `STATUS_REFUSED` (if pending). - Session marked as `'cancelled'`. ### Example URL ``` https://community.com/moneymotion/webhook/cancel?t=42&csrf_token=abc123def456... ``` ``` -------------------------------- ### Missing Webhook Secret Error Response Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/endpoints.md Example of an HTTP 500 Internal Server Error response when the webhook secret is not configured. ```HTTP HTTP/1.1 500 Internal Server Error Content-Type: application/json {"error": "Webhook secret not configured"} ``` -------------------------------- ### Check Gateway Feature Support Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/api-reference/gateway.md Determines if the gateway supports a specific feature like 'auth' or 'capture'. Use this to conditionally execute logic based on gateway capabilities. ```php class _moneymotion extends \IPS\nexus\Gateway ``` ```php public function supports( $feature ) ``` ```php $gateway = \IPS\nexus\Gateway::load('moneymotion'); if ($gateway->supports('auth')) { // Create a checkout session } ``` -------------------------------- ### Invalid Signature Error Response Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/endpoints.md Example of an HTTP 401 Unauthorized response indicating an invalid signature when validating a webhook request. ```HTTP HTTP/1.1 401 Unauthorized Content-Type: application/json {"error": "Invalid signature"} ``` -------------------------------- ### Gateway Hook Implementation Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/configuration.md Injects the moneymotion gateway into the \IPS\nexus\Gateway::gateways() method. ```php class moneymotion_hook_Gateway extends _HOOK_CLASS_ { public static function gateways() { $gateways = parent::gateways(); $gateways['moneymotion'] = 'IPS\moneymotion\extensions\nexus\Gateway\moneymotion'; return $gateways; } } ``` -------------------------------- ### testSettings($settings) Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/api-reference/gateway.md Validates gateway settings before saving. Throws an InvalidArgumentException if the API key or webhook secret is empty. ```APIDOC ## testSettings($settings) ### Description Validates gateway settings before saving. ### Method public function testSettings( $settings ) ### Parameters #### Path Parameters - **settings** (array) - Required - Settings array with keys: `api_key`, `webhook_secret` ### Return Type `array` ### Returns The validated settings array ### Throws `InvalidArgumentException` if: - API key is empty - Webhook secret is empty ### Example ```php try { $validated = $gateway->testSettings([ 'api_key' => 'mk_live_...', 'webhook_secret' => 'whsk_...' ]); } catch (InvalidArgumentException $e) { echo $e->getMessage(); } ``` ``` -------------------------------- ### auth($transaction, $values, $maxMind, $recurrings, $source) Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/api-reference/gateway.md Creates a checkout session and redirects the customer to moneymotion for payment. This method handles the initial payment authorization process. ```APIDOC ## `auth($transaction, $values, $maxMind, $recurrings, $source)` ### Description Creates a checkout session and redirects the customer to moneymotion for payment. ### Method `auth` ### Parameters #### Path Parameters - `$transaction` (\IPS\nexus\Transaction) - Required - The transaction record (will be saved if no ID) - `$values` (array|\IPS\nexus\Customer\CreditCard) - Required - Form values (not used by moneymotion) - `$maxMind` (\IPS\nexus\Fraud\MaxMind\Request|null) - Optional - MaxMind fraud detection request - `$recurrings` (array) - Optional - Recurring payment details - `$source` (string|null) - Optional - Payment source: 'checkout' or 'renewal' ### Returns - `\IPS\DateTime|null` - NULL (auth validation not used; payment finalized via webhook) ### Throws - `\LogicException` - if customer email is missing/invalid - `\LogicException` - if API call fails ### Side Effects - Saves transaction if no ID yet - Stores session in `moneymotion_sessions` table - Redirects customer to `https://moneymotion.io/checkout/{sessionId}` ### Example ```php try { $gateway->auth($transaction, [], null, [], 'checkout'); } catch (\LogicException $e) { // Handle validation error echo $e->getMessage(); } ``` ``` -------------------------------- ### Moneymotion API Key Settings Labels Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/configuration.md Language keys for the API key setting label and its description. ```php 'moneymotion_api_key' => "moneymotion API Key" 'moneymotion_api_key_desc' => "Enter your moneymotion API key (starts with mk_live_ or mk_test_)." ``` -------------------------------- ### Return URLs Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/README.md Handles customer returns to the website after payment processing. ```APIDOC ## GET /moneymotion/webhook/success ### Description Handles the customer's return to the website after a successful payment. ### Method GET ### Endpoint /moneymotion/webhook/success ### Response #### Success Response (200) - **message** (string) - A confirmation message indicating successful return. #### Response Example { "message": "Payment successful. You will be redirected shortly." } ``` ```APIDOC ## GET /moneymotion/webhook/cancel ### Description Handles the customer's return to the website after cancelling the payment. ### Method GET ### Endpoint /moneymotion/webhook/cancel ### Response #### Success Response (200) - **message** (string) - A message indicating the payment was cancelled. #### Response Example { "message": "Payment cancelled. You may return to the store." } ``` ```APIDOC ## GET /moneymotion/webhook/failure ### Description Handles the customer's return to the website after a payment failure. ### Method GET ### Endpoint /moneymotion/webhook/failure ### Response #### Success Response (200) - **message** (string) - A message indicating the payment failed. #### Response Example { "message": "Payment failed. Please try again." } ``` -------------------------------- ### Create Checkout Session Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/api-reference/api-client.md Initiate a new checkout session with the moneymotion backend. This method requires details such as a description, callback URLs, customer email, line items, and optionally metadata and currency. It returns a session ID used to construct the checkout URL. ```php try { $sessionId = $client->createCheckoutSession( 'Invoice #42', [ 'success' => 'https://community.com/moneymotion/webhook/success?t=1&csrf_token=...', 'cancel' => 'https://community.com/moneymotion/webhook/cancel?t=1&csrf_token=...', 'failure' => 'https://community.com/moneymotion/webhook/failure?t=1&csrf_token=...' ], 'customer@example.com', [ [ 'name' => 'Membership', 'description' => 'Payment for Invoice #42', 'pricePerItemInCents' => 2999, // $29.99 'quantity' => 1 ] ], ['invoice_id' => 42, 'transaction_id' => 1], 'USD' ); // Redirect customer to checkout header("Location: https://moneymotion.io/checkout/{$sessionId}"); } catch (\RuntimeException $e) { echo "Failed to create checkout: " . $e->getMessage(); } ``` -------------------------------- ### GET /moneymotion/webhook/failure Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/endpoints.md Handles customer redirection when a payment fails on the Moneymotion checkout. It validates the CSRF token, updates the transaction status, and redirects the user to the invoice checkout page. ```APIDOC ## GET /moneymotion/webhook/failure ### Description Customer redirected here if payment fails on moneymotion checkout. The plugin validates the CSRF token, marks the transaction as refused if pending, and redirects the customer to the invoice checkout URL with a "moneymotion_payment_failed" flash message. ### Method GET ### Endpoint /moneymotion/webhook/failure ### Parameters #### Query Parameters - **t** (int) - Yes - Transaction ID - **csrf_token** (string) - Yes - CSRF token for validation ### Response #### Success Response (302 Redirect) - Redirects to invoice checkout URL. - Flash message: "moneymotion_payment_failed" ### Example URL https://community.com/moneymotion/webhook/failure?t=42&csrf_token=abc123def456... ``` -------------------------------- ### General Log Format Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/errors.md The standard format for logging messages within the 'moneymotion' channel. This format ensures consistent and informative log entries. ```php \IPS\Log::log("moneymotion: {message} - {details}", 'moneymotion'); ``` -------------------------------- ### Get Currency Minor Unit Multiplier Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/api-reference/gateway.md Returns the ISO 4217 minor unit multiplier for a given currency. This is crucial for accurate amount calculations. Handles zero, two, and three-decimal currencies. ```php $multiplier = $gateway::currencyMinorUnitMultiplier('JPY'); // Returns: 1 ``` ```php $multiplier = $gateway::currencyMinorUnitMultiplier('USD'); // Returns: 100 ``` -------------------------------- ### Module Configuration Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/configuration.md Defines the webhook module within the front application for the Moneymotion plugin. ```json { "front": { "gateway": { "default_controller": "webhook", "protected": 0 } } } ``` -------------------------------- ### Get Client IP Address Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/api-reference/webhook-controller.md Extracts the client's IP address for audit logging, prioritizing specific headers like X-Forwarded-For. Validates the IP and logs both forwarded and actual addresses. ```php protected function getClientIp() { // ... implementation details ... } ``` -------------------------------- ### Extension Configuration Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/configuration.md Registers the gateway as a nexus payment method extension. ```json { "nexus": { "Gateway": [ "moneymotion" ] } } ``` -------------------------------- ### settings(&$form) Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/api-reference/gateway.md Renders the gateway settings form in the ACP for administrators to configure their API key and webhook secret. ```APIDOC ## settings(&$form) ### Description Renders the gateway settings form in the ACP for administrators to configure their API key and webhook secret. ### Method public function settings( &$form ) ### Parameters #### Path Parameters - **form** (` ips exusForm`) - Required - Form object to add settings fields to ### Return Type `void` ### Settings Fields Added - `moneymotion_api_key` — API key (starts with `mk_live_` or `mk_test_`) - `moneymotion_webhook_secret` — Webhook signing secret from moneymotion dashboard ### Example ```php $form = new ips exusForm(); $gateway->settings($form); ``` ``` -------------------------------- ### Constructing Success Return URL Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/endpoints.md PHP code snippet demonstrating how to construct a success return URL with a generated CSRF token. ```PHP $csrfTokenSuccess = $this->generateCsrfToken($transaction->id, 'success'); $urls['success'] = 'https://community.com/moneymotion/webhook/success?t=' . $transaction->id . '&csrf_token=' . $csrfTokenSuccess; ``` -------------------------------- ### Hook Configuration Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/configuration.md Defines the Gateway hook that injects moneymotion into the gateway list. ```json { "Gateway": { "type": "C", "class": "\\IPS\\nexus\\Gateway" } } ``` -------------------------------- ### moneymotion Payment Flow Diagram Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/README.md Illustrates the step-by-step process of a customer making a payment using the moneymotion gateway within Invision Community. ```text ┌─────────────────────────────────────────────────────────────┐ │ │ │ 1. Customer clicks "Pay with moneymotion" │ │ ↓ │ │ 2. Creates checkout session at moneymotion API │ │ ↓ │ │ 3. Redirects to moneymotion checkout page │ │ (https://moneymotion.io/checkout/{id}) │ │ ↓ │ │ 4. Customer enters payment details & confirms │ │ ↓ │ │ 5. moneymotion processes payment │ │ ↓ │ │ 6. Webhook sent to your IPS community │ │ (checkout_session:complete event) │ │ ↓ │ │ 7. Transaction marked as PAID ✅ │ │ │ └─────────────────────────────────────────────────────────────┘ ``` -------------------------------- ### Logging Missing Customer Email Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/errors.md This snippet demonstrates logging a message when the customer email is missing or invalid. This is a preliminary step before throwing a LogicException. ```php \IPS\Log::log( "moneymotion: missing/invalid customer email - transaction_id: {$transaction->id}...", 'moneymotion' ); ``` -------------------------------- ### Moneymotion Application Metadata Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/configuration.md Configuration for the Moneymotion application metadata, including title, author, version, and website. ```json { "application_title": "moneymotion Payment Gateway", "app_directory": "moneymotion", "app_author": "moneymotion", "app_version": "3.0.18", "app_long_version": 30018, "app_protected": 0, "app_website": "https://moneymotion.io", "app_update_check": "" } ``` -------------------------------- ### paymentScreen($invoice, $amount, $member, $recurrings, $type) Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/api-reference/gateway.md Renders the payment screen that displays to the customer before redirecting to moneymotion checkout. Returns HTML with a "Pay with moneymotion" button. ```APIDOC ## paymentScreen($invoice, $amount, $member, $recurrings, $type) ### Description Renders the payment screen that displays to the customer before redirecting to moneymotion checkout. ### Method public function paymentScreen( ips exusInvoice $invoice, ips exusMoney $amount, ? ips exusCustomer $member = NULL, $recurrings = array(), $type = 'checkout' ) ### Parameters #### Path Parameters - **invoice** (` ips exusInvoice`) - Required - The invoice being paid - **amount** (` ips exusMoney`) - Required - Amount to pay (includes currency) - **member** (` ips exusCustomer`|null) - Optional - Default: NULL - The customer (null for guests) - **recurrings** (array) - Optional - Default: `array()` - Recurring payment details - **type** (string) - Optional - Default: `'checkout'` - Transaction type (always 'checkout') ### Return Type `string` (HTML) ### Returns Rendered template with "Pay with moneymotion" button ``` -------------------------------- ### supports($feature) Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/api-reference/gateway.md Determines whether the gateway supports a specific feature, such as authorization or capture. moneymotion performs auth+capture in one step via webhook. ```APIDOC ## supports($feature) ### Description Determines whether the gateway supports a specific feature. ### Method public function supports( $feature ) ### Parameters #### Path Parameters - **feature** (string) - Required - Feature name to check (e.g. 'auth', 'capture') ### Return Type `bool` ### Supported Features - `'auth'` — Authorization/payment creation - `'capture'` — Payment capture (note: moneymotion performs auth+capture in one step via webhook) ### Example ```php $gateway = ips exusGateway::load('moneymotion'); if ($gateway->supports('auth')) { // Create a checkout session } ``` ``` -------------------------------- ### Furl Routing Configuration Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/configuration.md Maps friendly URLs to internal controller routes for the Moneymotion plugin. ```json { "topLevel": "moneymotion", "pages": { "webhook": { "friendly": "webhook", "real": "app=moneymotion&module=gateway&controller=webhook" }, ... } } ``` -------------------------------- ### Gateway Settings Structure Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/types.md The structure for gateway settings stored as a JSON string in `IPS\nexus\Gateway->settings`. It requires an API key and a webhook secret. ```php array( 'api_key' => string, 'webhook_secret' => string ) ``` -------------------------------- ### Moneymotion Database Schema Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/configuration.md Defines the structure of the `moneymotion_sessions` table, including columns for session ID, transaction ID, invoice ID, amount, currency, status, and timestamps. ```sql CREATE TABLE `moneymotion_sessions` ( `session_id` VARCHAR(255) NOT NULL PRIMARY KEY, `transaction_id` BIGINT(20) NOT NULL DEFAULT 0, `invoice_id` BIGINT(20) NOT NULL DEFAULT 0, `amount_cents` INT(11) NOT NULL DEFAULT 0, `currency` VARCHAR(3) NOT NULL DEFAULT 'EUR', `status` VARCHAR(32) NOT NULL DEFAULT 'pending', `created_at` INT(10) NOT NULL DEFAULT 0, `updated_at` INT(10) NOT NULL DEFAULT 0 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; ``` -------------------------------- ### Handling API Communication Errors with RuntimeException Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/errors.md This code block illustrates exception handling during the creation of a checkout session. It catches generic exceptions, logs the error, and re-throws a LogicException for user-facing feedback. ```php try { $sessionId = $client->createCheckoutSession(...); } catch (\Exception $e) { \IPS\Log::log("moneymotion createCheckoutSession failed: " . $e->getMessage(), 'moneymotion'); throw new \LogicException(\IPS\Member::loggedIn()->language()->addToStack('moneymotion_error_api')); } ``` -------------------------------- ### Request/Response Flow Diagram Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/endpoints.md A diagram illustrating the flow of customer requests, IPS plugin actions, and Moneymotion interactions during the payment process. ```Diagram CUSTOMER IPS PLUGIN MONEYMOTION | | | |-- Checkout Form Submit ----| | | |-- Create Session API -------->| | |<------ Session ID ------------| |<--- Redirect to Checkout --| | | | |------------- Enter Payment Details ---------------------->| | | |<-------- Webhook: Payment Complete --| | | |-- Approve Txn --| | | | |<----------- Redirect to Success ----| | | | ``` -------------------------------- ### handleCheckoutRefunded Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/api-reference/webhook-controller.md Processes a refunded payment event (`checkout_session:refunded`). It finds the session, loads the transaction, and updates their statuses to reflect the refund. ```APIDOC ## handleCheckoutRefunded(array $payload) ### Description Processes a refunded payment event (`checkout_session:refunded`). It finds the session, loads the transaction, and updates their statuses to reflect the refund. ### Method Signature `protected function handleCheckoutRefunded( array $payload )` ### Parameters #### Request Body - **$payload** (array) - Required - Full webhook payload containing `event` and `checkoutSession` details. ### Payload Structure Example ```php array( 'event' => 'checkout_session:refunded', 'checkoutSession' => array( 'id' => 'sess_...' ) ) ``` ### Side Effects 1. Finds session by session ID 2. Loads transaction 3. Sets transaction status to `STATUS_REFUNDED` 4. Updates session status to `'refunded'` 5. Logs refund ``` -------------------------------- ### Moneymotion Payment Button Language Key Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/configuration.md Defines the language key for the 'Pay with moneymotion' button. ```php 'moneymotion_pay_button' => "Pay with moneymotion" ``` -------------------------------- ### handleCheckoutComplete Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/api-reference/webhook-controller.md Processes a successful payment event (`checkout_session:complete`). It validates the session, transaction, and amount before marking the payment as complete. ```APIDOC ## handleCheckoutComplete(array $payload) ### Description Processes a successful payment event (`checkout_session:complete`). It validates the session, transaction, and amount before marking the payment as complete. ### Method Signature `protected function handleCheckoutComplete( array $payload )` ### Parameters #### Request Body - **$payload** (array) - Required - Full webhook payload containing `event` and `checkoutSession` details. ### Payload Structure Example ```php array( 'event' => 'checkout_session:complete', 'checkoutSession' => array( 'id' => 'sess_...', 'totalInCents' => 2999 ) ) ``` ### Side Effects 1. Updates session status: `pending` → `processing` (atomic) 2. Loads IPS transaction 3. Approves transaction via `$transaction->approve()` 4. Updates session status: `processing` → `complete` 5. Logs successful payment with amount ### Error Scenarios Handled Internally - Missing session ID - Session not found in database - Session already complete (idempotency) - Session not claimable (racing webhook) - Transaction not found - Amount mismatch (cents comparison) - Currency mismatch (if present in payload) - Transaction approval fails ``` -------------------------------- ### Webhook Response on Missing Gateway Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/errors.md Illustrates the HTTP response when a gateway is not found or configured. This indicates a critical misconfiguration that prevents webhook processing. ```http HTTP/1.1 500 Internal Server Error Content-Type: application/json {"error": "Gateway not configured"} ``` -------------------------------- ### Render Payment Screen Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/api-reference/gateway.md Renders the HTML for the payment screen presented to the customer before redirecting to the moneymotion checkout. It includes a 'Pay with moneymotion' button. ```php public function paymentScreen( \IPS\nexus\Invoice $invoice, \IPS\nexus\Money $amount, ?\IPS\nexus\Customer $member = NULL, $recurrings = array(), $type = 'checkout' ) ``` -------------------------------- ### Check Card Storage Support Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/api-reference/gateway.md Verifies if the gateway allows storing payment cards. moneymotion does not support card storage. ```php public function canStoreCards( $adminCreatableOnly = FALSE ) ``` -------------------------------- ### Line Item Structure Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/types.md Defines the structure for a line item object. Each item requires a name, description, price in cents, and quantity. ```php array( 'name' => string, 'description' => string, 'pricePerItemInCents' => int, 'quantity' => int ) ``` -------------------------------- ### Find Moneymotion Gateway Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/api-reference/webhook-controller.md Locates the moneymotion gateway record in the database. It can return a full Gateway object, a fallback stub, or null if not found. ```php protected function findGateway() { // ... implementation details ... } // Example Usage: /* $gateway = $this->findGateway(); if ($gateway) { $settings = json_decode($gateway->settings, true); $secret = $settings['webhook_secret']; } */ ``` -------------------------------- ### Webhook Default Dispatcher Method Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/api-reference/webhook-controller.md The default method that routes all incoming requests to the webhook handler. ```php protected function manage() ``` -------------------------------- ### Catching InvalidArgumentException for Empty API Key Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/errors.md This snippet demonstrates how to catch an InvalidArgumentException when testing gateway settings with an empty API key. It's useful for validating API credentials before making critical calls. ```php try { $validated = $gateway->testSettings([ 'api_key' => '', // Empty 'webhook_secret' => 'whsk_...' ]); } catch (\InvalidArgumentException $e) { echo $e->getMessage(); // "moneymotion API key is required." } ``` -------------------------------- ### canStoreCards($adminCreatableOnly) Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/api-reference/gateway.md Determines whether the gateway supports storing payment cards. moneymotion does not support card storage. ```APIDOC ## canStoreCards($adminCreatableOnly) ### Description Determines whether the gateway supports storing payment cards. ### Method public function canStoreCards( $adminCreatableOnly = FALSE ) ### Parameters #### Path Parameters - **adminCreatableOnly** (bool) - Optional - Default: FALSE - If TRUE, only return gateways where the admin can create new options ### Return Type `bool` ### Returns `false` — moneymotion does not support card storage ``` -------------------------------- ### Moneymotion Redirect Message Language Key Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/configuration.md Defines the language key for the message displayed before redirecting to moneymotion for payment. ```php 'moneymotion_redirect_message' => "You will be redirected to moneymotion to complete your payment." ``` -------------------------------- ### success Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/api-reference/webhook-controller.md Handles successful payment return via a dedicated URL, validating the transaction and redirecting the user. ```APIDOC ## `success()` ### Description Handles successful payment return from the moneymotion checkout page via a return URL. It validates the transaction and CSRF token, then redirects the user to the invoice page with a success message. ### Method GET ### Endpoint `/moneymotion/webhook/success` ### Parameters #### Path Parameters None #### Query Parameters * **`t`** (string) - Required - Transaction ID. * **`csrf_token`** (string) - Required - CSRF token for validation. ### Request Example `GET /moneymotion/webhook/success?t=txn_123abc&csrf_token=abcdef123456` ### Response #### Success Response Redirects to the invoice URL with the message "moneymotion_payment_success". #### Response Example Redirects to: `/invoice/inv_xyz?message=moneymotion_payment_success` ### On Failure Redirects home with the message "moneymotion_payment_failed" if CSRF validation fails. ``` -------------------------------- ### Authenticate Transaction with Moneymotion Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/api-reference/gateway.md Initiates a checkout session with Moneymotion to process a customer's payment. Handles potential validation errors during the process. This method is used for initiating new payments. ```php try { $gateway->auth($transaction, [], null, [], 'checkout'); } catch (\\\LogicException $e) { // Handle validation error echo $e->getMessage(); } ``` -------------------------------- ### Handle Success Return URL Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/api-reference/webhook-controller.md Handles successful payment returns from the moneymotion checkout page. Redirects to the invoice page with a success message after validating the CSRF token. ```php protected function success() { // ... implementation details ... } ``` -------------------------------- ### Return URL Flow Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/README.md Illustrates the sequence of events when a customer makes a payment and is redirected to a return URL, including CSRF token validation. ```text Customer makes payment on moneymotion ↓ moneymotion redirects to return URL with CSRF token ↓ Plugin validates CSRF token (timing-safe) ↓ Plugin loads transaction (fallback: generic message) ↓ Plugin redirects to invoice or checkout ``` -------------------------------- ### POST /webhook Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/api-reference/webhook-controller.md Processes incoming moneymotion webhook notifications. This endpoint is responsible for receiving, validating, and routing various payment-related events from moneymotion. ```APIDOC ## POST /webhook ### Description Processes incoming moneymotion webhook notifications. This endpoint is responsible for receiving, validating, and routing various payment-related events from moneymotion. ### Method POST ### Endpoint /webhook ### Parameters #### Query Parameters None #### Request Body - **Raw POST body** (JSON) - Required - The webhook payload containing event details. ### Request Example ```json { "event": "checkout_session:complete", "checkoutSession": { "id": "sess_...", "totalInCents": 2999 } } ``` ### Response #### Success Response (200 OK) - **status** (string) - Indicates successful processing, e.g., "ok". #### Error Response (400 Bad Request, 401 Unauthorized, 500 Internal Server Error) - **error** (string) - Describes the error, e.g., "Invalid payload, missing signature, or stale timestamp". ### Response Example ```json { "status": "ok" } ``` ### Security Checks - Empty body rejection - Invalid payload rejection - Signature verification (mandatory) - Optional timestamp validation ### Event Routing - `checkout_session:complete`: Handled by `handleCheckoutComplete()` - `checkout_session:refunded`: Handled by `handleCheckoutRefunded()` - `checkout_session:expired`: Handled by `handleCheckoutFailed()` - `checkout_session:disputed`: Handled by `handleCheckoutFailed()` - Other events are logged without action. ``` -------------------------------- ### Callback URLs Structure Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/types.md Defines the structure for callback URLs used to redirect customers after checkout. Includes success, cancel, and failure URLs. ```php array( 'success' => string, 'cancel' => string, 'failure' => string ) ``` -------------------------------- ### Moneymotion Gateway Name Language Key Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/configuration.md Defines the language key for the gateway's display name. ```php 'gateway__moneymotion' => "moneymotion" ``` -------------------------------- ### Capture Payment (No-op for Moneymotion) Source: https://github.com/emergente-labs/moneymotion-invision-plugin/blob/main/_autodocs/api-reference/gateway.md This method is a no-operation for the Moneymotion gateway as payments are automatically captured upon authentication via webhook. ```php public function capture( \ IPS\ nexus\ Transaction $transaction ) { // No operation needed } ```