Documentation Index Fetch the complete documentation index at: https://docs.synapsebuilder.org/llms.txt
Use this file to discover all available pages before exploring further.
Overview
Payment Customization Functions let you show, hide, or reorder payment methods based on cart contents, customer data, or other conditions.
Use Cases
Hide Payment Methods Remove options based on conditions
Hide COD for high-value orders
Remove Buy Now Pay Later for B2B
Restrict payment by location
Reorder Methods Change payment method order
Promote preferred methods
Push expensive methods down
Prioritize by customer segment
Rename Methods Customize payment method names
Add processing fees
Show savings
Clarify payment terms
Conditional Display Complex payment logic
VIP payment methods
Location-based options
Cart value restrictions
How It Works
Checkout Loads
Customer reaches payment method selection in checkout
Function Executes
Your function receives cart data and available payment methods
Methods Customized
Function returns which methods to show/hide and their order
Checkout Updates
Payment method list updates based on function output
Example: Hide COD for High-Value Orders
Generate a function that hides cash on delivery for expensive orders:
Describe Your Function
Create a payment customization function that hides the
"Cash on Delivery" payment method when the cart total
is over $200. For orders under $200, show all payment
methods as normal.
Review Generated Code
Synapse creates:
Function logic (Rust or JavaScript)
Input query for cart and payment data
Customization rules
Configuration
Deploy & Test
Automatic validation
Deployed to dev store
Test with different cart totals
Activate Function
Payment functions are automatically active once deployed
Generated Function Structure
extensions/payment-customization/
├── src/
│ ├── run.rs # Function logic (Rust)
│ │ OR
│ ├── run.js # Function logic (JS)
│ └── run.graphql # Input query
├── shopify.extension.toml # Config
└── Cargo.toml / package.json
Function Code Examples
use shopify_function :: prelude ::* ;
use shopify_function :: Result ;
#[shopify_function_target(
query_path = "src/run.graphql" ,
schema_path = "schema.graphql"
)]
fn run ( input : input :: ResponseData ) -> Result < output :: FunctionRunResult > {
// Calculate cart total
let cart_total : f64 = input
. cart
. cost
. subtotal_amount
. amount
. parse ()
. unwrap_or ( 0.0 );
// Find COD payment method
let operations = input
. payment_methods
. iter ()
. filter_map ( | method | {
// Check if this is Cash on Delivery
if method . name . to_lowercase () . contains ( "cash" ) {
// Hide if cart over $200
if cart_total > 200.0 {
return Some ( output :: Operation :: Hide ( output :: HideOperation {
payment_method_id : method . id . clone (),
}));
}
}
None
})
. collect ();
Ok ( output :: FunctionRunResult {
operations ,
})
}
export function run ( input ) {
const isVIP = input . cart . buyerIdentity ?. customer ?. hasTag ?.( 'vip' ) || false ;
const operations = [];
// Find preferred payment method
const preferredMethod = input . paymentMethods . find (
method => method . name . includes ( 'Express Checkout' )
);
if ( isVIP && preferredMethod ) {
// Move to top for VIP customers
operations . push ({
move: {
paymentMethodId: preferredMethod . id ,
index: 0
}
});
}
return { operations };
}
// Add fee to payment method name
let operations = input
. payment_methods
. iter ()
. filter_map ( | method | {
if method . name . contains ( "Credit Card" ) {
Some ( output :: Operation :: Rename ( output :: RenameOperation {
payment_method_id : method . id . clone (),
name : format! ( "{} (+3% fee)" , method . name),
}))
} else {
None
}
})
. collect ();
query RunInput {
cart {
cost {
subtotalAmount {
amount
}
}
buyerIdentity {
customer {
id
hasTags ( tags : [ "vip" , "wholesale" ])
}
}
}
paymentMethods {
id
name
}
}
Common Patterns
Show/hide payment methods based on order total: let cart_total : f64 = input . cart . cost . subtotal_amount . amount
. parse ()
. unwrap_or ( 0.0 );
let operations = input . payment_methods
. iter ()
. filter_map ( | method | {
match method . name . as_str () {
"Cash on Delivery" if cart_total > 200.0 => {
Some ( Operation :: Hide ( HideOperation {
payment_method_id : method . id . clone (),
}))
},
"Buy Now Pay Later" if cart_total < 50.0 => {
Some ( Operation :: Hide ( HideOperation {
payment_method_id : method . id . clone (),
}))
},
_ => None ,
}
})
. collect ();
Prompt Example: "Hide Cash on Delivery for orders over $200. Hide Buy Now Pay
Later for orders under $50. Show all other payment methods."
Customer Segment Restrictions
Different payment methods for different customers: let is_wholesale = input . cart . buyer_identity
. as_ref ()
. and_then ( | identity | identity . customer . as_ref ())
. map ( | customer | customer . has_tags ( vec! [ "wholesale" ]))
. unwrap_or ( false );
if is_wholesale {
// Only show Net 30 for wholesale customers
let operations = input . payment_methods
. iter ()
. filter_map ( | method | {
if ! method . name . contains ( "Net 30" ) {
Some ( Operation :: Hide ( HideOperation {
payment_method_id : method . id . clone (),
}))
} else {
None
}
})
. collect ();
}
Prompt Example: "For customers tagged 'wholesale', only show the Net 30 payment
option. Hide all other payment methods for wholesale customers."
Product-Based Restrictions
Payment restrictions based on cart contents: let has_restricted_product = input . cart . lines
. iter ()
. any ( | line | {
line . merchandise . product . has_tags ( vec! [ "restricted" ])
});
if has_restricted_product {
// No COD for restricted products
let operations = input . payment_methods
. iter ()
. filter_map ( | method | {
if method . name . contains ( "Cash on Delivery" ) {
Some ( Operation :: Hide ( HideOperation {
payment_method_id : method . id . clone (),
}))
} else {
None
}
})
. collect ();
}
Prompt Example: "If cart contains any products tagged 'high-value', hide Cash
on Delivery and Buy Now Pay Later options. Only allow credit
card payments."
Location-Based Restrictions
Different payment options by shipping address: let country = input . cart . delivery_address
. as_ref ()
. map ( | addr | addr . country_code . as_str ())
. unwrap_or ( "" );
let operations = input . payment_methods
. iter ()
. filter_map ( | method | {
match ( country , method . name . as_str ()) {
( "IN" , name ) if name . contains ( "Cash on Delivery" ) => None ,
( _ , "Cash on Delivery" ) => {
Some ( Operation :: Hide ( HideOperation {
payment_method_id : method . id . clone (),
}))
},
_ => None ,
}
})
. collect ();
Prompt Example: "Only show Cash on Delivery for customers in India. Hide it
for all other countries."
Operation Types
Payment customization functions support three operations:
Remove a payment method from the list: Operation :: Hide ( HideOperation {
payment_method_id : method . id . clone (),
})
Use when:
Payment method not allowed
Condition not met
Customer segment restriction
Change payment method position: Operation :: Move ( MoveOperation {
payment_method_id : method . id . clone (),
index : 0 , // Move to top
})
Use when:
Promoting preferred methods
Prioritizing by customer
Ordering by fee
Update payment method display name: Operation :: Rename ( RenameOperation {
payment_method_id : method . id . clone (),
name : format! ( "{} (2.9% + 30¢)" , method . name),
})
Use when:
Showing processing fees
Adding clarifications
Displaying savings
Testing Payment Functions
Test in Checkout
Add items to cart
Go to checkout
Proceed to payment methods
Verify correct methods appear
Test Different Scenarios
Different cart values
Various customer types
Multiple product combinations
Different shipping addresses
Check Function Logs
shopify app function logs
View function input/output
Verify Performance
Functions should execute in under 5ms
Test with many payment methods
Check with large carts
Best Practices
Always Show Some Method Never hide all payment methods // Ensure at least one method remains
let visible_count = input . payment_methods . len ()
- hide_operations . len ();
if visible_count == 0 {
// Don't hide everything
return Ok ( FunctionRunResult {
operations : vec! [],
});
}
Clear Naming Make renamed methods descriptive // Good: Clear fee structure
name : "Credit Card (3% fee)"
// Bad: Vague
name : "Credit Card (extra charge)"
Fallback Logic Handle missing data gracefully let cart_total = input . cart . cost . subtotal_amount . amount
. parse :: < f64 >()
. unwrap_or ( 0.0 ); // Default to 0
Performance Keep functions fast
Minimize iterations
Use Rust for speed
Cache calculations
Limit query surface
Advanced Examples
let operations = input . payment_methods
. iter ()
. map ( | method | {
let fee_percentage = match method . name . as_str () {
name if name . contains ( "Credit Card" ) => 2.9 ,
name if name . contains ( "PayPal" ) => 3.5 ,
_ => 0.0 ,
};
if fee_percentage > 0.0 {
let fee_amount = cart_total * ( fee_percentage / 100.0 );
Operation :: Rename ( RenameOperation {
payment_method_id : method . id . clone (),
name : format! (
"{} (+${:.2} processing fee)" ,
method . name,
fee_amount
),
})
} else {
Operation :: Rename ( RenameOperation {
payment_method_id : method . id . clone (),
name : method . name . clone (),
})
}
})
. collect ();
Prioritize by Customer Tier
let customer_tier = input . cart . buyer_identity
. as_ref ()
. and_then ( | id | id . customer . as_ref ())
. and_then ( | c | {
if c . has_tags ( vec! [ "tier-gold" ]) { Some ( 3 ) }
else if c . has_tags ( vec! [ "tier-silver" ]) { Some ( 2 ) }
else if c . has_tags ( vec! [ "tier-bronze" ]) { Some ( 1 ) }
else { Some ( 0 ) }
})
. unwrap_or ( 0 );
let mut operations = vec! [];
// Move preferred methods to top based on tier
if customer_tier >= 2 {
if let Some ( express ) = input . payment_methods . iter ()
. find ( | m | m . name . contains ( "Express" )) {
operations . push ( Operation :: Move ( MoveOperation {
payment_method_id : express . id . clone (),
index : 0 ,
}));
}
}
let cart_total = parse_amount ( & input . cart . cost . subtotal_amount . amount);
let is_international = input . cart . delivery_address
. as_ref ()
. map ( | addr | addr . country_code != "US" )
. unwrap_or ( false );
let has_subscription = input . cart . lines . iter ()
. any ( | line | line . merchandise . product . has_tags ( vec! [ "subscription" ]));
let operations = input . payment_methods
. iter ()
. filter_map ( | method | {
// Complex rules
if method . name . contains ( "Cash on Delivery" ) {
if is_international || cart_total > 200.0 || has_subscription {
return Some ( Operation :: Hide ( HideOperation {
payment_method_id : method . id . clone (),
}));
}
}
if method . name . contains ( "Buy Now Pay Later" ) {
if cart_total < 50.0 || has_subscription {
return Some ( Operation :: Hide ( HideOperation {
payment_method_id : method . id . clone (),
}));
}
}
None
})
. collect ();
Example Prompts
Hide COD for International
Create a payment customization function that hides Cash on
Delivery for any orders shipping outside the United States.
Check the shipping address country code.
For customers tagged 'vip', move the Express Checkout payment
method to the top of the list. Keep all other methods in their
default order.
Rename payment methods to show processing fees: Credit Card
shows +2.9%, PayPal shows +3.5%, and Bank Transfer shows +'Free'.
Display the fee percentage after the method name.
Subscription Restrictions
If cart contains any products tagged 'subscription', only allow
Credit Card and Bank Transfer payment methods. Hide all other
payment options including COD and Buy Now Pay Later.
Troubleshooting
Cause: Function hiding all payment methodsSolution: Add safeguard to ensure at least one method remains visible
Cause: Name matching logic incorrectSolution: Check exact payment method name, use contains() or regex
Cause: Function not activatedSolution: Payment functions activate automatically on deployment, check logs
Next Steps
Shipping Customization Customize shipping rates and options
Discount Functions Create custom discount logic
Functions Overview Learn about all function types
Debugging Debug and optimize functions