Webjala
Register Login

StockSmart to PennyPipe Integration Guide

StockSmart

This guide explains how business users can send StockSmart sales and purchasing transactions to a PennyPipe account.

What can be synced

You can sync these transaction types:

  • Sales

    • Sales documents

    • Customer payments

  • Purchasing

    • Purchase documents

    • Supplier payments

Each sync route sends entries to one specific PennyPipe account.

Before you start

Please confirm:

  • You have access to the PennyPipe integration page in StockSmart.

  • You know the target PennyPipe Account ID.

  • You have valid authentication details for PennyPipe (OAuth credentials or a PAT token).

  • Your PennyPipe user/client is allowed to post ledger entries to that account.

  • If using OAuth, your PennyPipe account must allowlist your OAuth client for integration ledger posting (your implementation/support team can help if you see 403).

Step 1: Open PennyPipe integration

In StockSmart, open:

  • Platform -> PennyPipe

Step 2: Create a connection

In OAuth/PAT connections, click Save connection after filling the fields.

Common fields:

  • Label

  • PennyPipe API Base URL (provided by your implementation/support team)

  • Auth Type (OAuth or PAT)

If using OAuth:

  • Identity Authority

  • Client ID

  • Client Secret

  • Scopes

If using PAT:

  • Personal Access Token

Tip: Give the connection a clear label such as Main Finance Account.

Step 3: Add a stream route

In Stream routes, create one route per target account and business flow.

Required choices:

  • Connection

  • Stream type (Sales or Purchasing)

  • PennyPipe Account ID

  • Enabled = checked

You can maintain separate routes for:

  • Sales -> Account A

  • Purchasing -> Account B

Step 4: Configure rules

Each route has rules for document and payment events.
For each enabled rule, set:

  • EntryType (credit or debit)

  • optional TagNames and CreateMissingTags

  • optional NoteTemplate

  • optional ReferenceIdSourceProperty (recommended; see below)

  • optional CustomFieldValueMaps (ledger custom fields; see below)

Example note templates

  • Sale #{ReceiptNumber} total {Total}

  • Customer payment {Payment} for {CustomerDetails}

  • Purchase #{ReceiptNumber} total {Total}

  • Supplier payment {Payment} to {SupplierDetails}

Mapping JSON examples (with explanation)

Use route rules JSON to control what StockSmart sends to PennyPipe for each event type. If your users are not editing JSON directly, your implementation/support team can paste these templates for you.

JSON key casing

  • Preferred JSON uses PascalCase keys (example: SalePayment, CustomFieldValueMaps, FieldDefinitionId).

  • The route editor accepts both PascalCase and camelCase when applying JSON, then normalizes it in the editor.

A) Sales mapping example

{
  "SaleDocument": {
    "Enabled": true,
    "EntryType": "credit",
    "TagNames": ["Sales", "Retail"],
    "CreateMissingTags": true,
    "ReferenceIdSourceProperty": "Id",
    "NoteTemplate": "Sale #{ReceiptNumber} | Customer: {CustomerDetails} | Total: {Total}",
    "CustomFieldValueMaps": [
      {
        "FieldDefinitionId": "11111111-1111-1111-1111-111111111111",
        "SourceProperty": "ReceiptNumber"
      },
      {
        "FieldDefinitionId": "22222222-2222-2222-2222-222222222222",
        "SourceProperty": "Notes"
      }
    ]
  },
  "SalePayment": {
    "Enabled": true,
    "EntryType": "credit",
    "TagNames": ["Customer payments"],
    "CreateMissingTags": true,
    "ReferenceIdSourceProperty": "Id",
    "NoteTemplate": "Payment #{ReceiptNumber} | Paid: {Payment} | Customer: {CustomerDetails}",
    "CustomFieldValueMaps": [
      {
        "FieldDefinitionId": "33333333-3333-3333-3333-333333333333",
        "SourceProperty": "Payment"
      },
      {
        "FieldDefinitionId": "44444444-4444-4444-4444-444444444444",
        "SourceProperty": "BankAccountName"
      }
    ]
  }
}

B) Purchasing mapping example

{
  "PurchaseDocument": {
    "Enabled": true,
    "EntryType": "debit",
    "TagNames": ["Purchases", "Suppliers"],
    "CreateMissingTags": true,
    "ReferenceIdSourceProperty": "Id",
    "NoteTemplate": "Purchase #{ReceiptNumber} | Supplier: {SupplierDetails} | Total: {Total}",
    "CustomFieldValueMaps": [
      {
        "FieldDefinitionId": "55555555-5555-5555-5555-555555555555",
        "SourceProperty": "ReceiptNumber"
      },
      {
        "FieldDefinitionId": "66666666-6666-6666-6666-666666666666",
        "SourceProperty": "Notes"
      }
    ]
  },
  "SupplierPayment": {
    "Enabled": true,
    "EntryType": "debit",
    "TagNames": ["Supplier payments"],
    "CreateMissingTags": true,
    "ReferenceIdSourceProperty": "Id",
    "NoteTemplate": "Supplier payment #{ReceiptNumber} | Paid: {Payment} | Supplier: {SupplierDetails}",
    "CustomFieldValueMaps": [
      {
        "FieldDefinitionId": "77777777-7777-7777-7777-777777777777",
        "SourceProperty": "Payment"
      },
      {
        "FieldDefinitionId": "88888888-8888-8888-8888-888888888888",
        "SourceProperty": "BankAccountName"
      }
    ]
  }
}

What each mapping field means

  • Enabled: turns that event mapping on/off.

  • EntryType: credit or debit in PennyPipe.

  • TagNames: tags added to the ledger entry.

  • CreateMissingTags: if true, missing tags are created automatically.

  • NoteTemplate: builds the note text using placeholders from StockSmart values.

  • CustomFieldValueMaps: maps StockSmart values to PennyPipe custom fields (extra fields).

  • ReferenceIdSourceProperty: optional source property used for PennyPipe entry.referenceId (account-scoped upsert key).

About note templates

NoteTemplate is optional but recommended for traceability.

Placeholders are case-insensitive and can reference any public property on the underlying entity for that event (for example {ReceiptNumber}, {Total}, {Payment}, {Notes}, {CustomerDetails}, {SupplierDetails}, {Id}).

If a placeholder value is empty, that part appears blank in the final note.

About extra fields (CustomFieldValueMaps)

Each item in CustomFieldValueMaps connects:

  • FieldDefinitionId: the PennyPipe custom field ID

  • SourceProperty: the StockSmart value to send into that field (case-insensitive public property name for that event)

Example:

  • Map PennyPipe field Invoice Ref to ReceiptNumber

  • Map PennyPipe field Internal Note to Notes

  • Map PennyPipe field Paid Amount to Payment

Tip: Copy FieldDefinitionId from the PennyPipe field list in the integration screen.

About ledger referenceId upserts

  • PennyPipe supports entry.referenceId for account-level upserts (same account + same referenceId = update instead of insert, when supported by PennyPipe).

  • StockSmart can send referenceId automatically (enabled by default). In rules, set ReferenceIdSourceProperty per event to control which StockSmart property becomes referenceId.

  • Default is Id (stable GUID from the StockSmart entity), which is recommended for deterministic re-runs/backfills.

  • Keep this value stable over time. Avoid random suffixes.

  • Important: Sale documents may be skipped if a usable referenceId can’t be resolved (to prevent duplicates during migrations/backfills). Using ReferenceIdSourceProperty: "Id" is the safest choice.

Custom field mapping: practical patterns

Below are common business patterns customers usually configure.

Pattern 1: Reference and remarks on sales documents

Goal: keep invoice reference and notes in PennyPipe custom fields.

{
  "SaleDocument": {
    "Enabled": true,
    "EntryType": "credit",
    "ReferenceIdSourceProperty": "Id",
    "CustomFieldValueMaps": [
      {
        "FieldDefinitionId": "a1111111-1111-1111-1111-111111111111",
        "SourceProperty": "ReceiptNumber"
      },
      {
        "FieldDefinitionId": "a2222222-2222-2222-2222-222222222222",
        "SourceProperty": "Notes"
      }
    ]
  }
}

Pattern 2: Payment-focused mapping

Goal: record paid amount and payment context for customer payments.

{
  "SalePayment": {
    "Enabled": true,
    "EntryType": "credit",
    "ReferenceIdSourceProperty": "Id",
    "CustomFieldValueMaps": [
      {
        "FieldDefinitionId": "b1111111-1111-1111-1111-111111111111",
        "SourceProperty": "Payment"
      },
      {
        "FieldDefinitionId": "b2222222-2222-2222-2222-222222222222",
        "SourceProperty": "BankAccountName"
      },
      {
        "FieldDefinitionId": "b3333333-3333-3333-3333-333333333333",
        "SourceProperty": "ReceiptNumber"
      }
    ]
  }
}

Pattern 3: Supplier-side mapping for purchasing

Goal: mirror supplier reference and comments for purchase-side entries.

{
  "PurchaseDocument": {
    "Enabled": true,
    "EntryType": "debit",
    "ReferenceIdSourceProperty": "Id",
    "CustomFieldValueMaps": [
      {
        "FieldDefinitionId": "c1111111-1111-1111-1111-111111111111",
        "SourceProperty": "ReceiptNumber"
      },
      {
        "FieldDefinitionId": "c2222222-2222-2222-2222-222222222222",
        "SourceProperty": "Notes"
      }
    ]
  },
  "SupplierPayment": {
    "Enabled": true,
    "EntryType": "debit",
    "ReferenceIdSourceProperty": "Id",
    "CustomFieldValueMaps": [
      {
        "FieldDefinitionId": "c3333333-3333-3333-3333-333333333333",
        "SourceProperty": "Payment"
      },
      {
        "FieldDefinitionId": "c4444444-4444-4444-4444-444444444444",
        "SourceProperty": "BankAccountName"
      }
    ]
  }
}

Recommended rollout method for custom fields

  1. Start with one event only (for example SaleDocument).

  2. Add 1-2 custom fields first (such as ReceiptNumber, Notes).

  3. Run a test post and verify values in PennyPipe.

  4. Expand mapping to payment events after validation.

Common mapping mistakes to avoid

  • Using a field ID from the wrong PennyPipe account.

  • Mapping payment rules with irrelevant values.

  • Changing many mappings at once and making troubleshooting hard.

  • Leaving old/unused custom fields in the route JSON.

  • Expecting null/blank StockSmart properties to be sent to PennyPipe custom fields (null values are omitted).

Step 5: (Optional) Map custom PennyPipe fields

If you use custom ledger fields in PennyPipe:

  1. Load ledger fields in the integration page.

  2. Add CustomFieldValueMaps inside the relevant event rule (for example SalePayment or SupplierPayment).

  3. Save the route.

Common values used in mapping:

  • ReceiptNumber

  • Payment

  • Total

  • Notes

  • CustomerDetails

  • SupplierDetails

Step 6: Run a test post

In Test & field definitions:

  1. Select the connection.

  2. Enter the account ID.

  3. Enter a small amount (for example 0.01).

  4. Click Test post.

If test is successful, you can go live.

Step 7: Go live and validate

Approve a real transaction in StockSmart and verify the ledger entry appears in PennyPipe with:

  • expected amount

  • expected credit/debit direction

  • expected tags

  • expected note/custom fields

Common issues and fixes

Test post says 403 (access denied)

This usually means the token/client does not have permission on that PennyPipe account.

Check:

  • correct account ID

  • correct connection selected

  • token/client has ledger post permission in PennyPipe

Test post fails with authentication errors

Check:

  • OAuth/PAT credentials are correct

  • token is active and not expired/revoked

  • PennyPipe API base URL is correct

Nothing appears in PennyPipe after approval

Check:

  • route is enabled

  • correct stream type (Sales vs Purchasing)

  • correct PennyPipe account on route

  • related event rule is enabled (document/payment)

Best practices

  • Create separate connections for test and production.

  • Use clear labels for each connection and route.

  • Keep token/client credentials secure and rotate regularly.

  • Start with a small test amount before full rollout.

Quick go-live checklist

  • Connection saved successfully

  • Route created for each required stream/account

  • Rules configured and enabled

  • Test post succeeded

  • Live transaction verified in PennyPipe

Payment troubleshooting

  • For purchase invoice payments, verify the route StreamType is Purchasing and rule SupplierPayment.Enabled is true.

  • If custom field values are empty in PennyPipe, re-check both FieldDefinitionId (correct account) and SourceProperty names, and confirm the underlying StockSmart property has a non-empty value for that transaction.