Merchant Pricing
Overview
Merchant pricing lets you define how processing charges are calculated for a merchant and then apply those charges over a chosen time period.
A PricingPlan holds a set of PricingRule records.
Each rule references a Highnote-managed rule template and supplies the parameter values that template expects.
A published plan is applied to a merchant during onboarding through a PricingConfiguration, which sets the period the plan is in effect.
Key concepts
| Concept | Definition |
|---|---|
PricingPlan | Named container for the rules that calculate a merchant's charges. Moves through a DRAFT → PUBLISHED → ARCHIVED lifecycle. |
PricingRule | Single charge within a plan. Supplies a rule template (ruleTemplateId on input, returned as templateId) and defines when it is evaluated through its trigger and frequency. |
PricingRuleParameter | Name-value pair that supplies an input the rule template expects (for example, a fixed fee or a percentage). |
PricingConfiguration | Associates a published plan with a merchant and a validity window (effectiveFrom through an optional effectiveThrough). |
PricingPlanStatus | Lifecycle state of a plan: DRAFT, PUBLISHED, or ARCHIVED. A plan's rules are set at creation and cannot be changed afterward. |
Pricing plan lifecycle
A pricing plan is created in DRAFT with its full set of rules, and cannot be changed after the plan is created.
While a plan is in DRAFT it can be simulated but is not yet applied to transactions. Publishing makes the plan live for transaction processing.
A plan that is no longer in use moves to ARCHIVED, where it is retained for historical records and no longer applied to transactions.
| Step | Action | Plan status |
|---|---|---|
| 1 | Create a plan with its rules. | DRAFT |
| 2 | Simulate the plan against sample transactions to confirm the charges calculate correctly. | DRAFT |
| 3 | Publish the plan to make it live for transaction processing. | PUBLISHED |
A plan's rules are fixed when it is created — there is no operation to change a rule afterward. To revise pricing, create a new plan, simulate it, and publish it.
Rule templates
Each rule supplies a ruleTemplateId that points to a rule template, along with the parameter values that template expects. When you read a rule back, that reference is returned as templateId.
Each template defines the calculation logic for a charge and the named parameters a rule must supply. Templates are not created or queried through the pricing API. Contact your Highnote representative for the ruleTemplateId values available to your program and the parameter names each template expects.
Create pricing plan
Use createPricingPlan to create a plan together with all of its rules. New plans are created in DRAFT. A plan's rules are set here and cannot be changed afterward. To revise pricing, create a new plan.
Each rule supplies:
ruleTemplateId: Rule template providing the calculation logic.pricingRuleParameters: Parameter values the template expects, each anameand avalue.trigger: Event that evaluates the rule —TRANSACTION,BATCH, orRECURRING.frequency: How often the rule is evaluated —TRANSACTIONALorMONTHLY.
mutation CreatePricingPlan($input: CreatePricingPlanInput!) {
createPricingPlan(input: $input) {
... on PricingPlan {
id
name
status
rules(first: 20) {
edges {
node {
id
templateId
trigger
frequency
}
}
}
}
... on UserError {
errors {
code
description
}
}
}
}
{
"input": {
"name": "Standard Merchant Pricing",
"description": "Per-transaction fee plus a monthly service charge",
"pricingRules": [
{
"ruleTemplateId": "<TRANSACTION_RULE_TEMPLATE_ID>",
"trigger": "TRANSACTION",
"frequency": "TRANSACTIONAL",
"pricingRuleParameters": [
{ "name": "fixedFee", "value": { "single": "0.10" } },
{ "name": "variableFee", "value": { "single": "0.20" } }
]
},
{
"ruleTemplateId": "<MONTHLY_RULE_TEMPLATE_ID>",
"trigger": "RECURRING",
"frequency": "MONTHLY",
"pricingRuleParameters": [
{ "name": "monthlyFixedFee", "value": { "single": "100.00" } }
]
}
]
}
}
Simulate pricing plan
Use simulatePricingPlan to perform a dry run of a plan against sample transactions before you publish it. A plan can be simulated in any status.
You provide the sample transactions as a base64-encoded CSV in contextDataCsvBase64, and the mutation returns the calculated charges as a base64-encoded CSV in resultCsvBase64. Decode the result to review the charges.
Each row in the template is one sample transaction, keyed by transactionId. The remaining columns, prefixed pricing., supply the context the rules evaluate, grouped as:
- Transaction attributes: Per-transaction fields such as network, amount, card brand, entry mode, interchange, and merchant category code.
- Batch totals: Batch amount, currency, and transaction count.
- Merchant prior-month counts: Per-network authorization counts, plus AVS and PIN-debit counts.
- Payfac prior-month volumes: Settled and authorized transaction counts and payment volumes.
transactionId,pricing.transactionAcquirerNetwork,pricing.transactionAmount,pricing.transactionAmountCurrency,pricing.transactionAmountImpact,pricing.transactionAvs,pricing.transactionCardBrand,pricing.transactionCardPresent,pricing.transactionContactless,pricing.transactionCrossBorder,pricing.transactionChannel,pricing.transactionForeignExchange,pricing.transactionInterchangeAmount,pricing.transactionInterchangeAmountCurrency,pricing.transactionInterchangeAmountImpact,pricing.transactionInterchangePercentage,pricing.transactionKeyedIn,pricing.transactionMerchantCategoryCode,pricing.transactionType,pricing.transactionVirtualTerminal,pricing.transactionAuthTimestamp,pricing.transactionSettlementTimestamp,pricing.transactionFundingSource,pricing.transactionAuthorizationRequestCount,pricing.transactionPosTerminalType,pricing.transactionPanEntryMode,pricing.transactionPinEntryMode,pricing.transactionPinProvidedInd,pricing.transactionIsPinDebit,pricing.transactionAvsPostalCode,pricing.transactionCardBinVertical,pricing.batchTotalAmount,pricing.batchTotalAmountCurrency,pricing.batchTotalTransactionCount,pricing.merchantPreviousMonthVisaAuthCount,pricing.merchantPreviousMonthMastercardAuthCount,pricing.merchantPreviousMonthDiscoverAuthCount,pricing.merchantPreviousMonthAmericanExpressAuthCount,pricing.merchantPreviousMonthUnionPayAuthCount,pricing.merchantPreviousMonthJcbAuthCount,pricing.merchantPreviousMonthAvsCount,pricing.merchantPreviousMonthPinDebitCount,pricing.payfacPreviousMonthTotalSettledTransactionCount,pricing.payfacPreviousMonthTotalSettledTransactionPaymentVolumeAmount,pricing.payfacPreviousMonthTotalSettledTransactionPaymentVolumeAmountCurrency,pricing.payfacPreviousMonthTotalAuthTransactionCount,pricing.payfacPreviousMonthTotalAuthTransactionPaymentVolumeAmount,pricing.payfacPreviousMonthTotalAuthTransactionPaymentVolumeAmountCurrency
txn-1,Highnote,100.50,USD,CREDIT,MATCH,VISA,true,false,true,E_COMMERCE,false,1.75,USD,DEBIT,200,false,5411,PURCHASE,false,2026-03-15T14:30:25,2026-03-25T15:09:51,DEBIT,3,POS_TERMINAL,INTEGRATED_CIRCUIT_CARD,TERMINAL_HAS_PIN_ENTRY,true,true,ZIP5_MATCH,CONSUMER,25000.00,USD,100,600,350,50,30,15,8,500,20,5000,1250000.00,USD,5200,1300000.00,USD
Simulation accepts a maximum of 100 transactions per request. The template lists every column the simulation expects. Contact Highnote support if you need help populating it.
mutation SimulatePricingPlan($input: SimulatePricingPlanInput!) {
simulatePricingPlan(input: $input) {
... on PricingPlanSimulationResult {
resultCsvBase64
}
... on UserError {
errors {
code
description
}
}
}
}
{
"input": {
"pricingPlanId": "<PRICING_PLAN_ID>",
"contextDataCsvBase64": "<BASE64_ENCODED_CSV>"
}
}
Publish pricing plan
Use publishPricingPlan to transition a plan from DRAFT to PUBLISHED.
Once published, the plan is live for transaction processing.
mutation PublishPricingPlan($input: PublishPricingPlanInput!) {
publishPricingPlan(input: $input) {
... on PricingPlan {
id
name
status
}
... on UserError {
errors {
code
description
}
}
}
}
{
"input": {
"pricingPlanId": "<PRICING_PLAN_ID>"
}
}
Apply a plan
A published plan is applied to a merchant during onboarding, through the pricingPlanId field on the onboardPayfacMerchantBusinessOrganization mutation. Applying a plan records a PricingConfiguration — the link between the plan and the merchant, with the window it is in effect (effectiveFrom through an optional effectiveThrough).
Read a merchant's configurations through its payerPricingConfigurations field.
Find pricing configurations
Find the pricing configurations that apply to a merchant through its payerPricingConfigurations field. Each PricingConfiguration reports the plan that applies, the payer and payee, and the window it is in effect.
query MerchantPricingConfigurations($id: ID!) {
node(id: $id) {
... on Merchant {
id
payerPricingConfigurations(first: 20) {
pageInfo {
hasNextPage
endCursor
}
edges {
node {
id
pricingPlan {
id
name
status
}
payerEntityId
payeeEntityId
effectiveFrom
effectiveThrough
}
}
}
}
}
}
{
"id": "<MERCHANT_ID>"
}
Find pricing plans
Query an organization's pricing plans through the node interface, filtering by status with PricingPlanFilterInput.
query OrganizationPricingPlans($id: ID!, $filterBy: PricingPlanFilterInput) {
node(id: $id) {
... on Organization {
id
pricingPlans(first: 10, filterBy: $filterBy) {
pageInfo {
hasNextPage
endCursor
}
edges {
node {
id
name
description
status
}
}
}
}
}
}
{
"id": "<ORGANIZATION_ID>",
"filterBy": {
"status": "PUBLISHED"
}
}