[{"data":1,"prerenderedAt":2934},["ShallowReactive",2],{"header:help":3,"footer:default":67,"story:navigation\u002Fsearch:help":250,"story:help\u002Fcategories":288,"story:help\u002Fcategories\u002Fcustom-shipping-code":314,"help:categories:621d64cc-1acf-415b-9dd9-0492d1a683bf":342,"help:guides:621d64cc-1acf-415b-9dd9-0492d1a683bf":343,"help:tree:621d64cc-1acf-415b-9dd9-0492d1a683bf":344,"help:articles:621d64cc-1acf-415b-9dd9-0492d1a683bf":371,"story:contact":2744,"_apollo:default":2933},{"name":4,"created_at":5,"published_at":6,"updated_at":7,"id":8,"uuid":9,"content":10,"slug":57,"full_slug":58,"sort_by_date":59,"position":60,"tag_list":61,"is_startpage":24,"parent_id":62,"meta_data":59,"group_id":63,"first_published_at":64,"release_id":59,"lang":65,"path":59,"alternates":66,"default_full_slug":59,"translated_slugs":59},"Help Center Header","2024-08-09T18:06:34.939Z","2024-10-21T21:58:39.217Z","2024-10-21T21:58:39.232Z",10082752,"3e9b88f7-c163-4657-a2f2-62532d600fad",{"_uid":11,"link":12,"badge":16,"items":17,"title":13,"buttons":50,"new_tab":24,"submenu":51,"alignment":13,"component":52,"badge_link":53,"top_menu_items":56},"e5645a1a-f991-40e8-8d67-e40ebc082b5a",{"id":13,"url":13,"linktype":14,"fieldtype":15,"cached_url":13},"","story","multilink","Help Center",[18,27,34,39,44],{"_uid":19,"link":20,"title":23,"new_tab":24,"submenu":25,"component":26},"5cbe2861-1f49-4166-97da-a4dddd8105e3",{"id":21,"url":13,"linktype":14,"fieldtype":15,"cached_url":22},"4c0a2d99-ec30-4579-8ef1-6bf5564d4839","help\u002Fcategories\u002F","Articles",false,[],"header___item",{"_uid":28,"link":29,"title":32,"new_tab":33,"component":26},"1c8edeb5-b9e9-4cb8-b1c6-c1f292f7d7cd",{"id":13,"url":30,"linktype":31,"fieldtype":15,"cached_url":30},"https:\u002F\u002Fwiki.foxycart.com\u002F","url","Documentation",true,{"_uid":35,"link":36,"title":38,"new_tab":33,"component":26},"8d7df70e-f087-4da0-b616-6f0e9a5af35c",{"id":13,"url":37,"linktype":31,"fieldtype":15,"cached_url":37},"https:\u002F\u002Fapi.foxycart.com\u002F","API Documentation",{"_uid":40,"link":41,"title":43,"new_tab":33,"component":26},"f76e7944-23d5-4652-87e4-cdae79272762",{"id":13,"url":42,"linktype":31,"fieldtype":15,"cached_url":42},"https:\u002F\u002Fstatus.foxy.io\u002F","System Status",{"_uid":45,"link":46,"title":49,"new_tab":24,"component":26},"0de16771-4c84-466c-a1da-d8568113c71f",{"id":47,"url":13,"linktype":14,"fieldtype":15,"cached_url":48},"01e4e370-f9b9-45af-8fa9-f15540699b0d","contact","Contact Us",[],[],"header",{"id":54,"url":13,"linktype":14,"fieldtype":15,"cached_url":55},"4a679eb7-662d-4ea4-a976-5a2acbf0b663","help\u002F",[],"help-header","navigation\u002Fhelp-header",null,20,[],10082747,"71b81c2e-5e09-48a1-a397-a3c72fcd344a","2022-09-21T14:50:25.655Z","default",[],{"name":68,"created_at":69,"published_at":70,"updated_at":71,"id":72,"uuid":73,"content":74,"slug":243,"full_slug":244,"sort_by_date":59,"position":245,"tag_list":246,"is_startpage":24,"parent_id":62,"meta_data":59,"group_id":247,"first_published_at":248,"release_id":59,"lang":65,"path":59,"alternates":249,"default_full_slug":59,"translated_slugs":59},"Default Footer","2024-08-09T18:06:59.024Z","2025-09-04T06:24:46.223Z","2025-09-04T06:24:46.241Z",10082753,"e59e67ac-248a-482f-84a1-53d4f318186a",{"_uid":75,"about":76,"logos":77,"socials":82,"sections":108,"component":225,"cta_title":226,"bottom_links":227,"cta_subtitle":241,"cta_button_link":242,"cta_button_text":183},"830983f5-c4c4-43c8-b150-86a5e3fa6dc8","Foxy’s hosted cart & payment page allow you to sell anything, using your existing website or platform.",[78],{"id":79,"alt":13,"name":13,"focus":13,"title":13,"filename":80,"copyright":13,"fieldtype":81},14760,"https:\u002F\u002Fa-us.storyblok.com\u002Ff\u002F1001040\u002Fx\u002F3b030847ec\u002Fb-corp.svg","asset",[83,90,96,102],{"_uid":84,"icon":85,"link":86,"name":88,"component":89},"faf0a618-ea94-42ea-9182-03be18c43216","fa-facebook",{"id":13,"url":87,"linktype":31,"fieldtype":15,"cached_url":87},"https:\u002F\u002Fwww.facebook.com\u002Ffoxycart","Facebook","footer___social",{"_uid":91,"icon":92,"link":93,"name":95,"component":89},"14309c18-7e79-423e-b375-34555bac0811","fa-instagram",{"id":13,"url":94,"linktype":31,"fieldtype":15,"cached_url":94},"https:\u002F\u002Fwww.instagram.com\u002Ffoxy_io","Instagram",{"_uid":97,"icon":98,"link":99,"name":101,"component":89},"8f7fe7cf-0dd3-4596-8334-226ea466716a","fa-linkedin",{"id":13,"url":100,"linktype":31,"fieldtype":15,"cached_url":100},"https:\u002F\u002Fwww.linkedin.com\u002Fcompany\u002Ffoxycart.com","LinkedIn",{"_uid":103,"icon":104,"link":105,"name":107,"component":89},"90a675b4-dd97-40b5-be09-00a87223d4c5","fa-youtube",{"id":13,"url":106,"linktype":31,"fieldtype":15,"cached_url":106},"https:\u002F\u002Fwww.youtube.com\u002Fuser\u002Ffoxycart","Youtube",[109,139,184,206],{"_uid":110,"name":111,"items":112,"component":138},"82849945-282f-488c-b18d-a8d2252f514a","Company",[113,120,126,132],{"_uid":114,"link":115,"title":118,"new_tab":24,"component":119},"1f699ab1-938b-4d9d-9825-aabcbe6f57fe",{"id":116,"url":13,"linktype":14,"fieldtype":15,"cached_url":117},"63634293-a749-4226-9439-9f38ee6dcda0","about-us","About Us","footer___menu_items",{"_uid":121,"link":122,"title":125,"new_tab":24,"component":119},"b26b00f1-a0e7-4be2-8ab3-428b8cc841f8",{"id":123,"url":13,"linktype":14,"fieldtype":15,"cached_url":124},"26cb7c55-faed-4a77-a291-1552d4111b3e","how-foxy-works","How Foxy Works",{"_uid":127,"link":128,"title":131,"new_tab":24,"component":119},"b40c68a0-1ceb-4226-9515-6176534f61fe",{"id":129,"url":13,"linktype":14,"fieldtype":15,"cached_url":130},"dc6657d7-7f4f-4c0d-b781-e971b038ee26","for-good","Foxy For Good",{"_uid":133,"link":134,"title":137,"new_tab":24,"component":119},"3ad0c134-bef9-4fff-b891-e09f16109036",{"id":135,"url":13,"linktype":14,"fieldtype":15,"cached_url":136},"23cae210-baf4-4588-9862-d09f4f52ccd2","brand-assets","Brand Assets","footer___section",{"_uid":140,"name":141,"items":142,"component":138},"a6805fa8-ac60-47f1-b8f0-f27aded0afbe","Product",[143,149,155,161,167,173,179],{"_uid":144,"link":145,"title":148,"new_tab":24,"component":119},"b39c8a4e-2383-486f-b76a-11fbb15d8134",{"id":146,"url":13,"linktype":14,"fieldtype":15,"cached_url":147},"bb04690f-fe98-4ce6-80be-05b950f2364f","features\u002F","Features",{"_uid":150,"link":151,"title":154,"new_tab":24,"component":119},"64f8a41f-c181-433d-bc0a-fc94e71ecbf6",{"id":152,"url":13,"linktype":14,"fieldtype":15,"cached_url":153},"c450c58d-761d-48c0-a9af-0b064611689b","pricing","Pricing",{"_uid":156,"link":157,"title":160,"new_tab":24,"component":119},"6e0b287f-fd8c-4146-9e0e-0ab0b5c9ce3c",{"id":158,"url":13,"linktype":14,"fieldtype":15,"cached_url":159},"fab20ad9-e76a-4947-b709-3a6fdfa88028","blog\u002Fcategories\u002Fproduct-updates","Product Updates",{"_uid":162,"link":163,"title":166,"new_tab":24,"component":119},"47e5a074-a6b5-4f1c-8c2f-89a2ae9f83eb",{"id":164,"url":13,"linktype":14,"fieldtype":15,"cached_url":165},"d2c83612-d611-47f3-a3b4-ca7fe08540b8","changelogs\u002F","Changelogs",{"_uid":168,"link":169,"title":172,"new_tab":24,"component":119},"b5c08774-542f-4ffd-b357-c94d674488b9",{"id":170,"url":13,"linktype":14,"fieldtype":15,"cached_url":171},"08876121-0df3-4ed9-aa11-902b3e41cd02","whats-next","What's Next",{"_uid":174,"link":175,"title":178,"new_tab":24,"component":119},"9c2704ed-6d9f-43e1-9e67-c8d91c083288",{"id":176,"url":13,"linktype":14,"fieldtype":15,"cached_url":177},"056a7857-b18f-4025-8f97-91a38fc19bc8","compare\u002F","Compare",{"_uid":180,"link":181,"title":183,"new_tab":24,"component":119},"5f2db35b-674b-406a-8fa7-d246633af9fe",{"id":13,"url":182,"linktype":31,"fieldtype":15,"cached_url":182},"https:\u002F\u002Fadmin.foxy.io\u002Fsign-up","Try Foxy Free",{"_uid":185,"name":186,"items":187,"component":138},"63fa1f29-4252-4640-9922-fe310e69e54a","Security",[188,194,200],{"_uid":189,"link":190,"title":193,"new_tab":24,"component":119},"1158ddb6-9eb0-466f-8eb6-7ca2ae66c8b8",{"id":191,"url":13,"linktype":14,"fieldtype":15,"cached_url":192},"1f58fb2c-8681-4742-b6e8-09999beae9f6","security-contact","Security Contact",{"_uid":195,"link":196,"title":199,"new_tab":24,"component":119},"9a79c54a-6022-4dfd-854b-766f5e4703ba",{"id":197,"url":13,"linktype":14,"fieldtype":15,"cached_url":198},"55cbfcc3-425a-4261-8037-54e919851d2d","pci","PCI Compliance",{"_uid":201,"link":202,"title":205,"new_tab":24,"component":119},"0b85f5b6-9534-4071-b323-b39d053dd4d7",{"id":203,"url":13,"linktype":14,"fieldtype":15,"cached_url":204},"c3ac0fe3-83e2-4879-afbd-d4c83e1590df","help\u002Farticles\u002Four-official-domains-public-code","Domains & Codebases",{"_uid":207,"name":208,"items":209,"component":138},"998ded67-d107-49f4-8154-ca6be51671ec","Support",[210,213,216,219,222],{"_uid":211,"link":212,"title":16,"new_tab":24,"component":119},"594ffd35-3049-4004-bb08-0db568ebd819",{"id":54,"url":13,"linktype":14,"fieldtype":15,"cached_url":55},{"_uid":214,"link":215,"title":32,"new_tab":33,"component":119},"0a1a55ab-a985-4f9d-8b42-26da714d0c1c",{"id":13,"url":30,"linktype":31,"fieldtype":15,"cached_url":30},{"_uid":217,"link":218,"title":38,"new_tab":33,"component":119},"61e0b7c8-aadf-419b-a339-b3ccabc65bf4",{"id":13,"url":37,"linktype":31,"fieldtype":15,"cached_url":37},{"_uid":220,"link":221,"title":43,"new_tab":33,"component":119},"fd67a89e-1c54-4d31-94b5-64be999062d6",{"id":13,"url":42,"linktype":31,"fieldtype":15,"cached_url":42},{"_uid":223,"link":224,"title":49,"new_tab":24,"component":119},"231a6f71-e996-4ad4-b033-d4d5542f34f0",{"id":47,"url":13,"linktype":14,"fieldtype":15,"cached_url":48},"footer","Get started with our *unlimited free trial*.",[228,235],{"_uid":229,"link":230,"text":233,"component":234},"f0b77210-2632-45a2-8436-e57cad84d01a",{"id":231,"url":13,"linktype":14,"fieldtype":15,"cached_url":232},"60ba16a2-c1f4-485f-b978-8d2eeeafbf5a","terms-of-service","Terms of Service","footer___bottom_links",{"_uid":236,"link":237,"text":240,"component":234},"4bd497b0-993f-4b4d-a5b7-8a49c7c8fec9",{"id":238,"url":13,"linktype":14,"fieldtype":15,"cached_url":239},"332302b9-1d18-4016-b9c8-9b33c72d782b","privacy-policy","Privacy Policy","No credit card required.",{"id":13,"url":182,"linktype":31,"fieldtype":15,"cached_url":182},"default-footer","navigation\u002Fdefault-footer",50,[],"11006268-07f9-41e9-96f3-c51fb723399d","2022-09-21T20:39:02.357Z",[],{"name":251,"created_at":252,"published_at":253,"updated_at":254,"id":255,"uuid":256,"content":257,"slug":279,"full_slug":282,"sort_by_date":59,"position":283,"tag_list":284,"is_startpage":24,"parent_id":62,"meta_data":59,"group_id":285,"first_published_at":286,"release_id":59,"lang":65,"path":59,"alternates":287,"default_full_slug":59,"translated_slugs":59},"Search","2024-10-21T22:08:54.973Z","2025-05-26T09:17:25.790Z","2025-05-26T09:17:25.804Z",13592003,"14cbc359-9ac1-4a7a-a8de-ad4ac8ef26d4",{"_uid":258,"name":251,"indices":259,"summary":13,"component":279,"primary_image":280},"5e4a56e8-76f1-4790-b3a7-70f1be97d042",[260,265,269,274],{"key":261,"_uid":262,"icon":13,"name":263,"component":264},"all","c12a3210-7323-4273-8217-5215e52efe84","All","index",{"key":266,"_uid":267,"icon":268,"name":23,"component":264},"help_center_article","5acff080-95e4-44d3-8dcf-1b19720af382","fa-file-alt",{"key":270,"_uid":271,"icon":272,"name":273,"component":264},"help_center_guide","b8fbc206-c083-471e-a1f0-0ebeb90a669d","fa-book","Guides",{"key":275,"_uid":276,"icon":277,"name":278,"component":264},"blog_post","23419e83-2e56-4c4c-8a05-9fd1b3c9a9bd","fa-file-image","Blog Posts","search",{"id":59,"alt":59,"name":13,"focus":59,"title":59,"source":59,"filename":13,"copyright":59,"fieldtype":81,"meta_data":281},{},"navigation\u002Fsearch",60,[],"11e1fd31-95cd-4fc9-b736-8b8910663e6c","2024-10-21T23:17:05.904Z",[],{"name":23,"created_at":289,"published_at":290,"updated_at":291,"id":292,"uuid":21,"content":293,"slug":307,"full_slug":22,"sort_by_date":59,"position":308,"tag_list":309,"is_startpage":33,"parent_id":310,"meta_data":59,"group_id":311,"first_published_at":312,"release_id":59,"lang":65,"path":59,"alternates":313,"default_full_slug":59,"translated_slugs":59},"2022-09-19T14:42:29.685Z","2024-07-30T18:17:22.506Z","2024-07-30T18:17:22.525Z",2660,{"_uid":294,"icon":13,"name":23,"guides":295,"pinned":24,"summary":296,"category":13,"component":297,"blog_posts":298,"content_hub":24,"icon_custom":299,"case_studies":300,"faq_sections":301,"help_articles":302,"featured_guides":303,"mailbox_category":13,"featured_articles":304,"featured_blog_posts":305,"featured_case_studies":306},"d6dae89a-907a-4bf7-82de-fe2ba875ee6e",[],"Get your questions answered with our browsable knowledge base.","help_center_category",[],{"id":59,"alt":59,"name":13,"focus":59,"title":59,"filename":13,"copyright":59,"fieldtype":81},[],[],[],[],[],[],[],"categories",530,[],2658,"19ebcdd2-027f-47f5-9a5b-a8992c959578","2022-09-19T16:24:39.219Z",[],{"name":315,"created_at":316,"published_at":317,"updated_at":318,"id":319,"uuid":320,"content":321,"slug":335,"full_slug":336,"sort_by_date":59,"position":337,"tag_list":338,"is_startpage":24,"parent_id":310,"meta_data":59,"group_id":339,"first_published_at":340,"release_id":59,"lang":65,"path":59,"alternates":341,"default_full_slug":59,"translated_slugs":59},"Custom Shipping Code","2026-05-27T16:30:46.528Z","2026-06-24T21:24:10.404Z","2026-06-24T21:24:10.422Z",181083531435477,"621d64cc-1acf-415b-9dd9-0492d1a683bf",{"_uid":322,"icon":13,"name":315,"type":323,"pinned":24,"summary":324,"category":325,"component":297,"blog_posts":326,"icon_custom":327,"case_studies":329,"faq_sections":330,"featured_guides":331,"mailbox_category":13,"featured_articles":332,"featured_blog_posts":333,"featured_case_studies":334},"31421cb4-545f-42da-a2f6-c34d68e7f11f","simple","How to add, modify, or remove shipping rates with JavaScript in the Foxy admin.","d92c1375-75ba-48e1-bb02-a3ae35187e0b",[],{"id":59,"alt":59,"name":13,"focus":59,"title":59,"source":59,"filename":13,"copyright":59,"fieldtype":81,"meta_data":328},{},[],[],[],[],[],[],"custom-shipping-code","help\u002Fcategories\u002Fcustom-shipping-code",-290,[],"d9babca5-97b7-4d3f-b3d4-3f2de363a7b9","2026-05-28T20:17:53.353Z",[],[],[],[288,345],{"name":346,"created_at":347,"published_at":348,"updated_at":349,"id":350,"uuid":325,"content":351,"slug":365,"full_slug":366,"sort_by_date":59,"position":367,"tag_list":368,"is_startpage":24,"parent_id":310,"meta_data":59,"group_id":369,"first_published_at":348,"release_id":59,"lang":65,"path":59,"alternates":370,"default_full_slug":59,"translated_slugs":59},"Shipping","2023-01-19T16:28:43.170Z","2023-01-19T17:25:33.503Z","2026-05-19T18:05:41.768Z",28245,{"_uid":352,"icon":353,"name":346,"guides":354,"summary":355,"category":13,"component":297,"blog_posts":356,"content_hub":24,"icon_custom":357,"case_studies":358,"faq_sections":359,"help_articles":360,"featured_guides":361,"mailbox_category":13,"featured_articles":362,"featured_blog_posts":363,"featured_case_studies":364},"ea45a64b-f203-4c73-8645-325761de650e","fa-truck",[],"How to configure shipping rules for your store.",[],{"id":59,"alt":59,"name":13,"focus":59,"title":59,"filename":13,"copyright":59,"fieldtype":81},[],[],[],[],[],[],[],"shipping","help\u002Fcategories\u002Fshipping",90,[],"2e7778d1-fab7-4b53-ae55-f3382610fa56",[],[372,591,1193,1777,2037,2202,2422,2586],{"name":373,"created_at":374,"published_at":375,"updated_at":376,"id":377,"uuid":378,"content":379,"slug":584,"full_slug":585,"sort_by_date":59,"position":586,"tag_list":587,"is_startpage":24,"parent_id":588,"meta_data":59,"group_id":589,"first_published_at":375,"release_id":59,"lang":65,"path":59,"alternates":590,"default_full_slug":59,"translated_slugs":59},"Add Custom Shipping Code","2026-06-03T20:12:52.811Z","2026-06-03T20:57:51.884Z","2026-06-03T20:57:51.900Z",183615376684926,"bfd72855-b922-47e8-bd7d-5d43162103db",{"_uid":380,"body":381,"name":373,"image":579,"pinned":24,"summary":581,"category":320,"component":266,"related_articles":582},"b48fffab-6711-4490-9aae-3ff6808f7b9f",{"type":382,"content":383},"doc",[384,392,417,422,427,432,514,519,530,535,540,564,569],{"type":385,"attrs":386,"content":388},"heading",{"level":387,"textAlign":59},2,[389],{"text":390,"type":391},"Overview","text",{"type":393,"attrs":394,"content":395},"paragraph",{"textAlign":59},[396,398,406,408,415],{"text":397,"type":391},"This article walks through adding custom shipping code to your store from the Foxy admin. For what custom shipping code can do and how it works, see ",{"text":315,"type":391,"marks":399},[400],{"type":401,"attrs":402},"link",{"href":403,"uuid":404,"anchor":59,"target":405,"linktype":14},"\u002Fhelp\u002Farticles\u002Fcustom-shipping-code-overview","cec1151a-658b-481b-a38e-734203e38360","_self",{"text":407,"type":391},". For ready to use code, see ",{"text":409,"type":391,"marks":410},"Custom Shipping Code Examples",[411],{"type":401,"attrs":412},{"href":413,"uuid":414,"anchor":59,"target":405,"linktype":14},"\u002Fhelp\u002Farticles\u002Fcustom-shipping-code-examples","a8aa795a-3152-491a-91cc-b68c9674decd",{"text":416,"type":391},".",{"type":385,"attrs":418,"content":419},{"level":387,"textAlign":59},[420],{"text":421,"type":391},"Before you start",{"type":393,"attrs":423,"content":424},{"textAlign":59},[425],{"text":426,"type":391},"Custom shipping code runs for categories whose delivery type is set to \"Shipped using live shipping rates.\" Make sure the categories you want to affect are set to that delivery type and have a default weight configured. You can set this up in the Categories section of your admin.",{"type":385,"attrs":428,"content":429},{"level":387,"textAlign":59},[430],{"text":431,"type":391},"Steps",{"type":433,"attrs":434,"content":436},"ordered_list",{"order":435},1,[437,457,475,488,495,507],{"type":438,"content":439},"list_item",[440],{"type":393,"attrs":441,"content":442},{"textAlign":59},[443,445,450,452,455],{"text":444,"type":391},"In the Foxy admin, go to ",{"text":446,"type":391,"marks":447},"Settings",[448],{"type":449},"bold",{"text":451,"type":391}," and open the ",{"text":346,"type":391,"marks":453},[454],{"type":449},{"text":456,"type":391}," page.",{"type":438,"content":458},[459],{"type":393,"attrs":460,"content":461},{"textAlign":59},[462,464,468,470,473],{"text":463,"type":391},"In the ",{"text":465,"type":391,"marks":466},"Shipping methods",[467],{"type":449},{"text":469,"type":391}," list, click ",{"text":315,"type":391,"marks":471},[472],{"type":449},{"text":474,"type":391},". It will show as \"Inactive\" until you add code.",{"type":438,"content":476},[477],{"type":393,"attrs":478,"content":479},{"textAlign":59},[480,482,486],{"text":481,"type":391},"A ",{"text":483,"type":391,"marks":484},"New shipping method",[485],{"type":449},{"text":487,"type":391}," panel opens with a code editor labeled \"Custom Code.\"",{"type":438,"content":489},[490],{"type":393,"attrs":491,"content":492},{"textAlign":59},[493],{"text":494,"type":391},"Enter or paste your JavaScript into the editor. If you need help writing it you can reach out to the Foxy Support team.",{"type":438,"content":496},[497],{"type":393,"attrs":498,"content":499},{"textAlign":59},[500,502,506],{"text":501,"type":391},"Click ",{"text":503,"type":391,"marks":504},"Create",[505],{"type":449},{"text":416,"type":391},{"type":438,"content":508},[509],{"type":393,"attrs":510,"content":511},{"textAlign":59},[512],{"text":513,"type":391},"Foxy deploys your code behind the scenes. This takes about 15 to 20 seconds. Once deployed, Custom Shipping Code will show as \"Active\" in the Shipping methods list.",{"type":385,"attrs":515,"content":516},{"level":387,"textAlign":59},[517],{"text":518,"type":391},"Recommended: prevent rate tampering",{"type":393,"attrs":520,"content":521},{"textAlign":59},[522,524,528],{"text":523,"type":391},"On the same Shipping page, enable ",{"text":525,"type":391,"marks":526},"Prevent shipping rate tampering",[527],{"type":449},{"text":529,"type":391},". This signs each shipping rate and verifies it hasn't been altered between the cart and checkout submission. Leave this off only if you still rely on legacy browser side rate snippets.",{"type":385,"attrs":531,"content":532},{"level":387,"textAlign":59},[533],{"text":534,"type":391},"Test your code",{"type":393,"attrs":536,"content":537},{"textAlign":59},[538],{"text":539,"type":391},"Add a product from an eligible category to your cart and proceed to checkout with a shipping address. Your custom rates should appear among the shipping options. If you don't see the rates you expect:",{"type":541,"content":542},"bullet_list",[543,550,557],{"type":438,"content":544},[545],{"type":393,"attrs":546,"content":547},{"textAlign":59},[548],{"text":549,"type":391},"Confirm the product's category delivery type is \"Shipped using live shipping rates.\"",{"type":438,"content":551},[552],{"type":393,"attrs":553,"content":554},{"textAlign":59},[555],{"text":556,"type":391},"Confirm the code was saved and deployment finished (the method shows \"Active\").",{"type":438,"content":558},[559],{"type":393,"attrs":560,"content":561},{"textAlign":59},[562],{"text":563,"type":391},"Check that your code adds at least one rate (or returns an error) for the address you're testing.",{"type":385,"attrs":565,"content":566},{"level":387,"textAlign":59},[567],{"text":568,"type":391},"Edit or update your code",{"type":393,"attrs":570,"content":571},{"textAlign":59},[572,574,577],{"text":573,"type":391},"To change your code later, return to the Shipping page, click ",{"text":315,"type":391,"marks":575},[576],{"type":449},{"text":578,"type":391}," again, edit the code, and Save. Each save triggers a fresh deployment.",{"id":59,"alt":59,"name":13,"focus":59,"title":59,"source":59,"filename":13,"copyright":59,"fieldtype":81,"meta_data":580},{},"Step by step: add custom shipping code to your store.",[414,583,404],"7b057a6e-5277-42ef-8c0e-946e72139991","add-custom-shipping-code","help\u002Farticles\u002Fadd-custom-shipping-code",-1940,[],2659,"c43c2684-8bee-4f8c-a82e-abdcddf846ac",[],{"name":592,"created_at":593,"published_at":594,"updated_at":595,"id":596,"uuid":583,"content":597,"slug":1187,"full_slug":1188,"sort_by_date":59,"position":1189,"tag_list":1190,"is_startpage":24,"parent_id":588,"meta_data":59,"group_id":1191,"first_published_at":594,"release_id":59,"lang":65,"path":59,"alternates":1192,"default_full_slug":59,"translated_slugs":59},"Custom Shipping Code API Reference","2026-05-27T21:07:12.138Z","2026-05-28T21:09:22.488Z","2026-05-28T21:09:22.506Z",181151466090383,{"_uid":598,"body":599,"name":592,"image":1183,"pinned":24,"summary":1185,"category":320,"component":266,"related_articles":1186},"120eab7d-575a-47fe-aafe-8ed6fd5b6420",{"type":382,"content":600},[601,605,617,622,629,652,658,669,674,681,686,744,749,754,761,782,787,792,801,810,815,820,827,832,935,940,945,954,963,974,979,984,989,996,1040,1045,1050,1057,1062,1067,1077,1145,1150,1159,1168,1173],{"type":385,"attrs":602,"content":603},{"level":387,"textAlign":59},[604],{"text":390,"type":391},{"type":393,"attrs":606,"content":607},{"textAlign":59},[608,610,615],{"text":609,"type":391},"The ",{"text":611,"type":391,"marks":612},"rates",[613],{"type":614},"code",{"text":616,"type":391}," object is the primary interface for manipulating shipping rates in Custom Shipping Code. It's pre populated with any rates returned from carriers or the custom endpoint, and all methods are chainable (unless they return a value).",{"type":385,"attrs":618,"content":619},{"level":387,"textAlign":59},[620],{"text":621,"type":391},"Adding rates",{"type":393,"attrs":623,"content":624},{"textAlign":59},[625],{"text":626,"type":391,"marks":627},"rates.add(id, price, method, service_name)",[628],{"type":614},{"type":393,"attrs":630,"content":631},{"textAlign":59},[632,634,638,640,644,646,650],{"text":633,"type":391},"Adds a new rate. ",{"text":635,"type":391,"marks":636},"id",[637],{"type":614},{"text":639,"type":391}," must be 10000 or higher (if you pass a lower number, 10000 is added automatically). At least one of ",{"text":641,"type":391,"marks":642},"method",[643],{"type":614},{"text":645,"type":391}," or ",{"text":647,"type":391,"marks":648},"service_name",[649],{"type":614},{"text":651,"type":391}," is required. Pass an empty string for the one you don't need.",{"type":653,"attrs":654,"content":655},"code_block",{"class":59},[656],{"text":657,"type":391},"rates.add(10001, 5.99, 'FoxyPost', 'Standard');\nrates.add(10002, 0, '', 'Free Shipping');",{"type":393,"attrs":659,"content":660},{"textAlign":59},[661,663,667],{"text":662,"type":391},"Custom rates added with ",{"text":664,"type":391,"marks":665},"rates.add()",[666],{"type":614},{"text":668,"type":391}," do not automatically include handling fees or flat rates from other categories. Use the handling\u002Fflat rate helpers (below) if you need to include them.",{"type":385,"attrs":670,"content":671},{"level":387,"textAlign":59},[672],{"text":673,"type":391},"Filtering rates",{"type":393,"attrs":675,"content":676},{"textAlign":59},[677],{"text":678,"type":391,"marks":679},"rates.filter(selector)",[680],{"type":614},{"type":393,"attrs":682,"content":683},{"textAlign":59},[684],{"text":685,"type":391},"Returns a new Rates object containing only matching rates. The original collection is not modified. The selector can be:",{"type":541,"content":687},[688,704,726],{"type":438,"content":689},[690],{"type":393,"attrs":691,"content":692},{"textAlign":59},[693,694,698,700],{"text":481,"type":391},{"text":695,"type":391,"marks":696},"number",[697],{"type":449},{"text":699,"type":391}," — matches by ",{"text":701,"type":391,"marks":702},"service_id",[703],{"type":614},{"type":438,"content":705},[706],{"type":393,"attrs":707,"content":708},{"textAlign":59},[709,710,714,716,719,721,724],{"text":481,"type":391},{"text":711,"type":391,"marks":712},"string",[713],{"type":449},{"text":715,"type":391}," — matches against ",{"text":641,"type":391,"marks":717},[718],{"type":614},{"text":720,"type":391}," and ",{"text":647,"type":391,"marks":722},[723],{"type":614},{"text":725,"type":391}," (case insensitive)",{"type":438,"content":727},[728],{"type":393,"attrs":729,"content":730},{"textAlign":59},[731,733,737,739,742],{"text":732,"type":391},"An ",{"text":734,"type":391,"marks":735},"array of numbers",[736],{"type":449},{"text":738,"type":391}," — matches multiple ",{"text":701,"type":391,"marks":740},[741],{"type":614},{"text":743,"type":391}," values",{"type":653,"attrs":745,"content":746},{"class":59},[747],{"text":748,"type":391},"rates.filter(10001).price(0);\nrates.filter('fedex').hide();\nrates.filter([10001, 10002]).price('+5');",{"type":385,"attrs":750,"content":751},{"level":387,"textAlign":59},[752],{"text":753,"type":391},"Checking if rates exist",{"type":393,"attrs":755,"content":756},{"textAlign":59},[757],{"text":758,"type":391,"marks":759},"rates.exists([selector])",[760],{"type":614},{"type":393,"attrs":762,"content":763},{"textAlign":59},[764,766,770,772,775,777,781],{"text":765,"type":391},"Returns ",{"text":767,"type":391,"marks":768},"true",[769],{"type":614},{"text":771,"type":391}," if rates exist. If a selector is provided, returns ",{"text":767,"type":391,"marks":773},[774],{"type":614},{"text":776,"type":391}," only if matching rates exist. Selector works the same as ",{"text":778,"type":391,"marks":779},"filter()",[780],{"type":614},{"text":416,"type":391},{"type":653,"attrs":783,"content":784},{"class":59},[785],{"text":786,"type":391},"if (!rates.exists()) {\n  rates.add(10001, 15, '', 'Fallback Rate');\n}",{"type":385,"attrs":788,"content":789},{"level":387,"textAlign":59},[790],{"text":791,"type":391},"Showing and hiding rates",{"type":393,"attrs":793,"content":794},{"textAlign":59},[795,799],{"text":796,"type":391,"marks":797},"rates.hide()",[798],{"type":614},{"text":800,"type":391}," — hides the matched rates from the customer. Hidden rates remain in the collection and can still be filtered or shown later.",{"type":393,"attrs":802,"content":803},{"textAlign":59},[804,808],{"text":805,"type":391,"marks":806},"rates.show()",[807],{"type":614},{"text":809,"type":391}," — makes previously hidden rates visible again.",{"type":653,"attrs":811,"content":812},{"class":59},[813],{"text":814,"type":391},"rates.filter('usps').hide();\nrates.filter(10001).show();",{"type":385,"attrs":816,"content":817},{"level":387,"textAlign":59},[818],{"text":819,"type":391},"Modifying prices",{"type":393,"attrs":821,"content":822},{"textAlign":59},[823],{"text":824,"type":391,"marks":825},"rates.price(modifier)",[826],{"type":614},{"type":393,"attrs":828,"content":829},{"textAlign":59},[830],{"text":831,"type":391},"Sets or adjusts the price of matched rates. The modifier can be:",{"type":541,"content":833},[834,845],{"type":438,"content":835},[836],{"type":393,"attrs":837,"content":838},{"textAlign":59},[839,840,843],{"text":481,"type":391},{"text":695,"type":391,"marks":841},[842],{"type":449},{"text":844,"type":391}," — sets the price to that exact value",{"type":438,"content":846},[847,856],{"type":393,"attrs":848,"content":849},{"textAlign":59},[850,851,854],{"text":481,"type":391},{"text":711,"type":391,"marks":852},[853],{"type":449},{"text":855,"type":391}," with an operator prefix:",{"type":541,"content":857},[858,869,880,891,902,913,924],{"type":438,"content":859},[860],{"type":393,"attrs":861,"content":862},{"textAlign":59},[863,867],{"text":864,"type":391,"marks":865},"'+5'",[866],{"type":614},{"text":868,"type":391}," — adds 5 to the current price",{"type":438,"content":870},[871],{"type":393,"attrs":872,"content":873},{"textAlign":59},[874,878],{"text":875,"type":391,"marks":876},"'-5'",[877],{"type":614},{"text":879,"type":391}," — subtracts 5",{"type":438,"content":881},[882],{"type":393,"attrs":883,"content":884},{"textAlign":59},[885,889],{"text":886,"type":391,"marks":887},"'*2'",[888],{"type":614},{"text":890,"type":391}," — multiplies by 2",{"type":438,"content":892},[893],{"type":393,"attrs":894,"content":895},{"textAlign":59},[896,900],{"text":897,"type":391,"marks":898},"'\u002F2'",[899],{"type":614},{"text":901,"type":391}," — divides by 2",{"type":438,"content":903},[904],{"type":393,"attrs":905,"content":906},{"textAlign":59},[907,911],{"text":908,"type":391,"marks":909},"'=15'",[910],{"type":614},{"text":912,"type":391}," — sets to exactly 15 (same as passing a number)",{"type":438,"content":914},[915],{"type":393,"attrs":916,"content":917},{"textAlign":59},[918,922],{"text":919,"type":391,"marks":920},"'+20%'",[921],{"type":614},{"text":923,"type":391}," — adds 20% of the current price",{"type":438,"content":925},[926],{"type":393,"attrs":927,"content":928},{"textAlign":59},[929,933],{"text":930,"type":391,"marks":931},"'-20%'",[932],{"type":614},{"text":934,"type":391}," — subtracts 20% of the current price",{"type":653,"attrs":936,"content":937},{"class":59},[938],{"text":939,"type":391},"rates.filter('usps').price('+2.50');\nrates.filter(10001).price(0);\nrates.filter('fedex').price('-10%');",{"type":385,"attrs":941,"content":942},{"level":387,"textAlign":59},[943],{"text":944,"type":391},"Modifying labels",{"type":393,"attrs":946,"content":947},{"textAlign":59},[948,952],{"text":949,"type":391,"marks":950},"rates.method(string)",[951],{"type":614},{"text":953,"type":391}," — sets the carrier\u002Fmethod name for matched rates.",{"type":393,"attrs":955,"content":956},{"textAlign":59},[957,961],{"text":958,"type":391,"marks":959},"rates.service(string)",[960],{"type":614},{"text":962,"type":391}," — sets the service name for matched rates.",{"type":393,"attrs":964,"content":965},{"textAlign":59},[966,968,972],{"text":967,"type":391},"When called without an argument inside an ",{"text":969,"type":391,"marks":970},".each()",[971],{"type":614},{"text":973,"type":391}," callback, these return the current value.",{"type":653,"attrs":975,"content":976},{"class":59},[977],{"text":978,"type":391},"rates.filter('usps').method('US Postal Service');\nrates.filter(10001).service('Economy');",{"type":393,"attrs":980,"content":981},{"textAlign":59},[982],{"text":983,"type":391},"Note: HTML in method or service strings is not currently supported.",{"type":385,"attrs":985,"content":986},{"level":387,"textAlign":59},[987],{"text":988,"type":391},"Iterating over rates",{"type":393,"attrs":990,"content":991},{"textAlign":59},[992],{"text":993,"type":391,"marks":994},"rates.each(fn)",[995],{"type":614},{"type":393,"attrs":997,"content":998},{"textAlign":59},[999,1001,1005,1007,1011,1013,1017,1019,1023,1024,1028,1029,1033,1035,1039],{"text":1000,"type":391},"Calls ",{"text":1002,"type":391,"marks":1003},"fn",[1004],{"type":614},{"text":1006,"type":391}," for each matched rate. Inside the callback, ",{"text":1008,"type":391,"marks":1009},"this",[1010],{"type":614},{"text":1012,"type":391}," refers to the individual rate and exposes ",{"text":1014,"type":391,"marks":1015},".price()",[1016],{"type":614},{"text":1018,"type":391},", ",{"text":1020,"type":391,"marks":1021},".method()",[1022],{"type":614},{"text":1018,"type":391},{"text":1025,"type":391,"marks":1026},".service()",[1027],{"type":614},{"text":1018,"type":391},{"text":1030,"type":391,"marks":1031},".hide()",[1032],{"type":614},{"text":1034,"type":391},", and ",{"text":1036,"type":391,"marks":1037},".show()",[1038],{"type":614},{"text":416,"type":391},{"type":653,"attrs":1041,"content":1042},{"class":59},[1043],{"text":1044,"type":391},"rates.filter('fedex').each(function() {\n  this.service(this.service() + ' (Signature Required)');\n});",{"type":385,"attrs":1046,"content":1047},{"level":387,"textAlign":59},[1048],{"text":1049,"type":391},"Sorting",{"type":393,"attrs":1051,"content":1052},{"textAlign":59},[1053],{"text":1054,"type":391,"marks":1055},"rates.sort()",[1056],{"type":614},{"type":393,"attrs":1058,"content":1059},{"textAlign":59},[1060],{"text":1061,"type":391},"Sorts matched rates by price (ascending). Note that Foxy always re sorts rates ascending for display regardless of your code's ordering, so this is mainly useful if you need sorted iteration.",{"type":385,"attrs":1063,"content":1064},{"level":387,"textAlign":59},[1065],{"text":1066,"type":391},"Handling fees and flat rates",{"type":393,"attrs":1068,"content":1069},{"textAlign":59},[1070,1072,1075],{"text":1071,"type":391},"Custom rates added via ",{"text":664,"type":391,"marks":1073},[1074],{"type":614},{"text":1076,"type":391}," do not automatically include handling fees or flat rates from other categories in the cart. These helpers let you add or remove them:",{"type":541,"content":1078},[1079,1090,1101,1112,1123,1134],{"type":438,"content":1080},[1081],{"type":393,"attrs":1082,"content":1083},{"textAlign":59},[1084,1088],{"text":1085,"type":391,"marks":1086},"rates.addHandling()",[1087],{"type":614},{"text":1089,"type":391}," — adds handling fees from other categories to matched rates",{"type":438,"content":1091},[1092],{"type":393,"attrs":1093,"content":1094},{"textAlign":59},[1095,1099],{"text":1096,"type":391,"marks":1097},"rates.addFlatRate()",[1098],{"type":614},{"text":1100,"type":391}," — adds flat rate fees from other categories",{"type":438,"content":1102},[1103],{"type":393,"attrs":1104,"content":1105},{"textAlign":59},[1106,1110],{"text":1107,"type":391,"marks":1108},"rates.addHandlingAndFlatRate()",[1109],{"type":614},{"text":1111,"type":391}," — adds both",{"type":438,"content":1113},[1114],{"type":393,"attrs":1115,"content":1116},{"textAlign":59},[1117,1121],{"text":1118,"type":391,"marks":1119},"rates.removeHandling()",[1120],{"type":614},{"text":1122,"type":391}," — removes handling fees from matched rates",{"type":438,"content":1124},[1125],{"type":393,"attrs":1126,"content":1127},{"textAlign":59},[1128,1132],{"text":1129,"type":391,"marks":1130},"rates.removeFlatRate()",[1131],{"type":614},{"text":1133,"type":391}," — removes flat rate fees",{"type":438,"content":1135},[1136],{"type":393,"attrs":1137,"content":1138},{"textAlign":59},[1139,1143],{"text":1140,"type":391,"marks":1141},"rates.removeHandlingAndFlatRate()",[1142],{"type":614},{"text":1144,"type":391}," — removes both",{"type":385,"attrs":1146,"content":1147},{"level":387,"textAlign":59},[1148],{"text":1149,"type":391},"Errors and resets",{"type":393,"attrs":1151,"content":1152},{"textAlign":59},[1153,1157],{"text":1154,"type":391,"marks":1155},"rates.error(message)",[1156],{"type":614},{"text":1158,"type":391}," — sets an error message. If set, the error is displayed to the customer instead of any rates (error takes precedence).",{"type":393,"attrs":1160,"content":1161},{"textAlign":59},[1162,1166],{"text":1163,"type":391,"marks":1164},"rates.reset()",[1165],{"type":614},{"text":1167,"type":391}," — clears all rates and any error message.",{"type":385,"attrs":1169,"content":1170},{"level":387,"textAlign":59},[1171],{"text":1172,"type":391},"The cart object",{"type":393,"attrs":1174,"content":1175},{"textAlign":59},[1176,1177,1181],{"text":609,"type":391},{"text":1178,"type":391,"marks":1179},"cart",[1180],{"type":614},{"text":1182,"type":391}," object available in Custom Shipping Code contains the same payload sent to the Custom Shipping Endpoint. See the [Shipping Payload Reference] for the full structure, field descriptions, and common access patterns.",{"id":59,"alt":59,"name":13,"focus":59,"title":59,"source":59,"filename":13,"copyright":59,"fieldtype":81,"meta_data":1184},{},"Complete reference for the rates JavaScript API available in Custom Shipping Code feature of the Foxy Admin.",[],"custom-shipping-code-api-reference","help\u002Farticles\u002Fcustom-shipping-code-api-reference",-1900,[],"e7481619-f7c8-4d46-9be9-42733b938287",[],{"name":409,"created_at":1194,"published_at":1195,"updated_at":1196,"id":1197,"uuid":414,"content":1198,"slug":1771,"full_slug":1772,"sort_by_date":59,"position":1773,"tag_list":1774,"is_startpage":24,"parent_id":588,"meta_data":59,"group_id":1775,"first_published_at":1195,"release_id":59,"lang":65,"path":59,"alternates":1776,"default_full_slug":59,"translated_slugs":59},"2026-05-27T21:14:35.518Z","2026-05-28T21:09:22.251Z","2026-05-28T21:09:22.283Z",181153282191296,{"_uid":1199,"body":1200,"name":409,"image":1767,"pinned":24,"summary":1769,"category":320,"component":266,"related_articles":1770},"29e6a3ad-6b16-495f-b857-e0ecff0546bb",{"type":382,"content":1201},[1202,1206,1211,1226,1231,1236,1241,1246,1251,1256,1261,1266,1271,1276,1281,1286,1291,1296,1301,1306,1317,1322,1327,1332,1337,1342,1347,1352,1357,1362,1366,1371,1376,1381,1386,1391,1396,1401,1406,1411,1416,1421,1426,1431,1436,1441,1446,1451,1456,1461,1466,1471,1476,1481,1486,1491,1496,1501,1506,1511,1516,1521,1526,1531,1536,1541,1546,1551,1556,1561,1566,1571,1576,1581,1586,1591,1596,1601,1606,1611,1616,1621,1626,1631,1636,1641,1646,1651,1656,1661,1666,1671,1682,1687,1692,1697,1702,1707,1712,1717,1728,1733,1738,1747,1752,1757,1762],{"type":385,"attrs":1203,"content":1204},{"level":387,"textAlign":59},[1205],{"text":390,"type":391},{"type":393,"attrs":1207,"content":1208},{"textAlign":59},[1209],{"text":1210,"type":391},"These examples cover the most common shipping scenarios you can implement with Custom Shipping Code. Each one is self contained and can be pasted directly into the code editor in your Foxy admin. Combine and adapt them to fit your store's needs.",{"type":393,"attrs":1212,"content":1213},{"textAlign":59},[1214,1216,1219,1221,1224],{"text":1215,"type":391},"All examples use the two globals available in Custom Shipping Code: ",{"text":611,"type":391,"marks":1217},[1218],{"type":614},{"text":1220,"type":391}," (the shipping rates collection) and ",{"text":1178,"type":391,"marks":1222},[1223],{"type":614},{"text":1225,"type":391}," (the cart payload). For the full API reference, see [Custom Shipping Code API Reference]. For the complete payload structure, see [Shipping Payload Reference].",{"type":385,"attrs":1227,"content":1228},{"level":387,"textAlign":59},[1229],{"text":1230,"type":391},"Add a fallback rate",{"type":393,"attrs":1232,"content":1233},{"textAlign":59},[1234],{"text":1235,"type":391},"If no carriers return rates (for example, because of a network issue or unsupported destination), you can add a fallback so customers always have at least one option:",{"type":653,"attrs":1237,"content":1238},{"class":59},[1239],{"text":1240,"type":391},"if (!rates.exists()) {\n  rates.add(10001, 15, '', 'Standard Shipping');\n}",{"type":385,"attrs":1242,"content":1243},{"level":387,"textAlign":59},[1244],{"text":1245,"type":391},"Free shipping above a cart total",{"type":393,"attrs":1247,"content":1248},{"textAlign":59},[1249],{"text":1250,"type":391},"Add standard and express options, then make standard free when the cart subtotal reaches a threshold:",{"type":653,"attrs":1252,"content":1253},{"class":59},[1254],{"text":1255,"type":391},"rates.add(10001, 5, 'FoxyPost', 'Standard');\nrates.add(10002, 15, 'FoxyPost', 'Express');\n\nif (cart['_embedded']['fx:shipment']['total_item_price'] >= 40) {\n  rates.filter(10001).price(0).service('Free Shipping');\n}",{"type":385,"attrs":1257,"content":1258},{"level":387,"textAlign":59},[1259],{"text":1260,"type":391},"Tiered rates by cart total",{"type":393,"attrs":1262,"content":1263},{"textAlign":59},[1264],{"text":1265,"type":391},"Set different price points based on how much the customer is spending:",{"type":653,"attrs":1267,"content":1268},{"class":59},[1269],{"text":1270,"type":391},"const total = cart['_embedded']['fx:shipment']['total_item_price'];\nrates.add(10001, 75, 'FoxyPost', 'Standard');\n\nif (total \u003C= 200)       rates.filter(10001).price(0).service('Customer Pickup');\nelse if (total \u003C= 500)  rates.filter(10001).price(75);\nelse if (total \u003C= 1000) rates.filter(10001).price(150);\nelse                    rates.filter(10001).price(300);",{"type":385,"attrs":1272,"content":1273},{"level":387,"textAlign":59},[1274],{"text":1275,"type":391},"Adjust rates by weight",{"type":393,"attrs":1277,"content":1278},{"textAlign":59},[1279],{"text":1280,"type":391},"Change prices when the total weight exceeds a threshold:",{"type":653,"attrs":1282,"content":1283},{"class":59},[1284],{"text":1285,"type":391},"rates.add(10001, 5, 'FoxyPost', 'Standard');\nrates.add(10002, 9.45, 'FoxyPost', 'Priority');\nrates.add(10003, 10, 'FoxyPost', 'Express (Next Day)');\n\nif (cart['_embedded']['fx:shipment']['total_weight'] > 10) {\n  rates.filter(10001).price(6);\n  rates.filter(10002).price(10);\n  rates.filter(10003).price(11.99);\n}",{"type":385,"attrs":1287,"content":1288},{"level":387,"textAlign":59},[1289],{"text":1290,"type":391},"Hide a rate by item count",{"type":393,"attrs":1292,"content":1293},{"textAlign":59},[1294],{"text":1295,"type":391},"Remove an option when there are too many items (for example, disabling express for large orders):",{"type":653,"attrs":1297,"content":1298},{"class":59},[1299],{"text":1300,"type":391},"rates.add(10001, 5, 'FoxyPost', 'Standard');\nrates.add(10002, 9.45, 'FoxyPost', 'Priority');\nrates.add(10003, 10, 'FoxyPost', 'Express (Next Day)');\n\nif (cart['_embedded']['fx:shipment']['item_count'] > 5) {\n  rates.filter(10003).hide();\n}",{"type":385,"attrs":1302,"content":1303},{"level":387,"textAlign":59},[1304],{"text":1305,"type":391},"Free shipping with a coupon code",{"type":393,"attrs":1307,"content":1308},{"textAlign":59},[1309,1311,1315],{"text":1310,"type":391},"Check for a specific coupon code (or any code ending in ",{"text":1312,"type":391,"marks":1313},"-fs",[1314],{"type":614},{"text":1316,"type":391},") and replace all rates with a free option:",{"type":653,"attrs":1318,"content":1319},{"class":59},[1320],{"text":1321,"type":391},"const discounts = cart['_embedded']['fx:discounts'];\nfor (const d in discounts) {\n  const code = discounts[d]['code'];\n  if (code === 'freeshipping' || code.match(\u002F-fs$\u002Fi)) {\n    rates.hide();\n    rates.add(11000, 0, '', 'Free Shipping');\n  }\n}",{"type":385,"attrs":1323,"content":1324},{"level":387,"textAlign":59},[1325],{"text":1326,"type":391},"Country based tiered rates",{"type":393,"attrs":1328,"content":1329},{"textAlign":59},[1330],{"text":1331,"type":391},"Group countries into tiers and set a different rate for each:",{"type":653,"attrs":1333,"content":1334},{"class":59},[1335],{"text":1336,"type":391},"const tier1 = ['GB'];\nconst tier2 = ['AL','AD','AT','BE','BG','CH','CZ','DE','DK','EE','ES','FI','FR','GR','HU','HR','IE','IS','IT','LT','LU','LV','NL','NO','PL','PT','RO','SE','SI','SK'];\n\nconst country = cart['_embedded']['fx:shipment']['country'];\n\nif (tier1.includes(country))      rates.add(10001, 10, 'FoxyPost', 'Standard');\nelse if (tier2.includes(country)) rates.add(10002, 20, 'FoxyPost', 'International');\nelse                               rates.add(10003, 30, 'FoxyPost', 'International');",{"type":385,"attrs":1338,"content":1339},{"level":387,"textAlign":59},[1340],{"text":1341,"type":391},"Replace international rates with a flat rate",{"type":393,"attrs":1343,"content":1344},{"textAlign":59},[1345],{"text":1346,"type":391},"Hide all carrier rates for non domestic shipments and show a single custom rate instead:",{"type":653,"attrs":1348,"content":1349},{"class":59},[1350],{"text":1351,"type":391},"if (cart['_embedded']['fx:shipment']['country'] !== 'US') {\n  rates.hide();\n  rates.add(10001, 25, 'FoxyPost', 'Standard');\n}",{"type":385,"attrs":1353,"content":1354},{"level":387,"textAlign":59},[1355],{"text":1356,"type":391},"Modify carrier rate labels",{"type":393,"attrs":1358,"content":1359},{"textAlign":59},[1360],{"text":1361,"type":391},"Append text to all rates from a specific carrier (useful for adding notes like \"Signature Required\"):",{"type":653,"attrs":1363,"content":1364},{"class":59},[1365],{"text":1044,"type":391},{"type":385,"attrs":1367,"content":1368},{"level":387,"textAlign":59},[1369],{"text":1370,"type":391},"Add a surcharge to all rates",{"type":393,"attrs":1372,"content":1373},{"textAlign":59},[1374],{"text":1375,"type":391},"Apply a flat handling surcharge on top of whatever rates are already present:",{"type":653,"attrs":1377,"content":1378},{"class":59},[1379],{"text":1380,"type":391},"rates.price('+3.50');",{"type":393,"attrs":1382,"content":1383},{"textAlign":59},[1384],{"text":1385,"type":391},"Or a percentage:",{"type":653,"attrs":1387,"content":1388},{"class":59},[1389],{"text":1390,"type":391},"rates.price('+15%');",{"type":385,"attrs":1392,"content":1393},{"level":387,"textAlign":59},[1394],{"text":1395,"type":391},"Only show rates from one carrier",{"type":393,"attrs":1397,"content":1398},{"textAlign":59},[1399],{"text":1400,"type":391},"If you have multiple carriers enabled but want to limit what the customer sees based on a condition:",{"type":653,"attrs":1402,"content":1403},{"class":59},[1404],{"text":1405,"type":391},"if (cart['_embedded']['fx:shipment']['country'] === 'US') {\n  rates.filter('fedex').hide();\n} else {\n  rates.filter('usps').hide();\n}",{"type":385,"attrs":1407,"content":1408},{"level":387,"textAlign":59},[1409],{"text":1410,"type":391},"Block shipping to specific countries",{"type":393,"attrs":1412,"content":1413},{"textAlign":59},[1414],{"text":1415,"type":391},"Return an error instead of rates for unsupported destinations:",{"type":653,"attrs":1417,"content":1418},{"class":59},[1419],{"text":1420,"type":391},"const blocked = ['CU', 'IR', 'KP', 'SY'];\nconst country = cart['_embedded']['fx:shipment']['country'];\n\nif (blocked.includes(country)) {\n  rates.error('Sorry, we are unable to ship to your country.');\n}",{"type":385,"attrs":1422,"content":1423},{"level":387,"textAlign":59},[1424],{"text":1425,"type":391},"Category specific surcharges",{"type":393,"attrs":1427,"content":1428},{"textAlign":59},[1429],{"text":1430,"type":391},"Check what categories are in the cart and adjust rates accordingly. Each item has an embedded category code:",{"type":653,"attrs":1432,"content":1433},{"class":59},[1434],{"text":1435,"type":391},"const items = cart['_embedded']['fx:items'];\nconst country = cart['_embedded']['fx:shipment']['country'];\n\nconst hasFragile = items.some(item => item['_embedded']['fx:item_category']['code'] === 'fragile');\nconst hasOversized = items.some(item => item['_embedded']['fx:item_category']['code'] === 'oversized');\n\nlet baseRate = 7.99;\nif (hasFragile) baseRate += 5;\nif (hasOversized) baseRate += 10;\n\nrates.add(10001, baseRate, 'Shipping', 'Standard');\n\n\u002F\u002F Only offer express for non oversized domestic orders\nif (!hasOversized && country === 'US') {\n  rates.add(10002, baseRate + 8, 'Shipping', 'Express');\n}",{"type":385,"attrs":1437,"content":1438},{"level":387,"textAlign":59},[1439],{"text":1440,"type":391},"Weight based tiered pricing with international markup",{"type":393,"attrs":1442,"content":1443},{"textAlign":59},[1444],{"text":1445,"type":391},"Combine weight tiers with a multiplier for international shipments:",{"type":653,"attrs":1447,"content":1448},{"class":59},[1449],{"text":1450,"type":391},"const totalWeight = cart['_embedded']['fx:shipment']['total_weight'];\nconst country = cart['_embedded']['fx:shipment']['country'];\n\nlet standardPrice = 5;\nlet expressPrice = 12;\n\nif (totalWeight > 20) {\n  standardPrice = 15;\n  expressPrice = 30;\n} else if (totalWeight > 10) {\n  standardPrice = 10;\n  expressPrice = 20;\n} else if (totalWeight > 5) {\n  standardPrice = 7.50;\n  expressPrice = 15;\n}\n\n\u002F\u002F Double the price for international\nif (country !== 'US') {\n  standardPrice *= 2;\n  expressPrice *= 2;\n}\n\nrates.add(10001, standardPrice, 'Shipping', 'Standard');\nrates.add(10002, expressPrice, 'Shipping', 'Express');",{"type":385,"attrs":1452,"content":1453},{"level":387,"textAlign":59},[1454],{"text":1455,"type":391},"Per item pricing (base + additional items)",{"type":393,"attrs":1457,"content":1458},{"textAlign":59},[1459],{"text":1460,"type":391},"Charge a base rate for the first item plus a smaller amount for each additional item:",{"type":653,"attrs":1462,"content":1463},{"class":59},[1464],{"text":1465,"type":391},"const shipment = cart['_embedded']['fx:shipment'];\nconst itemCount = shipment['item_count'];\nconst country = shipment['country'];\n\nif (country === 'US') {\n  const standardCost = 10 + ((itemCount - 1) * 0.50);\n  const expressCost = 12 + ((itemCount - 1) * 1.50);\n  rates.add(10001, standardCost, 'FoxyPost', 'Standard');\n  rates.add(10002, expressCost, 'FoxyPost', 'Express');\n} else {\n  const intlCost = 15 + ((itemCount - 1) * 2);\n  rates.add(10003, intlCost, 'FoxyPost', 'International');\n}",{"type":385,"attrs":1467,"content":1468},{"level":387,"textAlign":59},[1469],{"text":1470,"type":391},"Per product shipping cost via item options",{"type":393,"attrs":1472,"content":1473},{"textAlign":59},[1474],{"text":1475,"type":391},"If products carry their own shipping cost as a hidden item option named \"shipping,\" sum them up:",{"type":653,"attrs":1477,"content":1478},{"class":59},[1479],{"text":1480,"type":391},"let productShipping = 0;\nconst items = cart['_embedded']['fx:items'];\n\nfor (const item of items) {\n  if (item['_embedded'] && item['_embedded']['fx:item_options']) {\n    for (const option of item['_embedded']['fx:item_options']) {\n      if (option['name'] === 'shipping' && !isNaN(parseFloat(option['value']))) {\n        productShipping += parseFloat(option['value']) * item['quantity'];\n      }\n    }\n  }\n}\n\nif (productShipping > 0) {\n  if (rates.exists()) {\n    rates.price('+' + productShipping);\n  } else {\n    rates.add(10001, productShipping, '', 'Standard Shipping');\n  }\n}",{"type":385,"attrs":1482,"content":1483},{"level":387,"textAlign":59},[1484],{"text":1485,"type":391},"Category based shipping lookup table",{"type":393,"attrs":1487,"content":1488},{"textAlign":59},[1489],{"text":1490,"type":391},"Map each category to a per item shipping cost:",{"type":653,"attrs":1492,"content":1493},{"class":59},[1494],{"text":1495,"type":391},"const categoryRates = {\n  'business-cards': 20,\n  'letterheads': 35,\n  'envelopes': 35,\n  'banners': 15,\n  't-shirts': 25,\n};\n\nlet shipping = 0;\nfor (const item of cart['_embedded']['fx:items']) {\n  const categoryCode = item['_embedded']['fx:item_category']['code'];\n  if (categoryRates[categoryCode]) {\n    shipping += item['quantity'] * categoryRates[categoryCode];\n  }\n}\n\nif (shipping > 0) {\n  rates.add(10001, shipping, '', 'Standard Shipping');\n} else {\n  rates.error(\"Sorry, we're unable to calculate shipping. Please contact us.\");\n}",{"type":385,"attrs":1497,"content":1498},{"level":387,"textAlign":59},[1499],{"text":1500,"type":391},"Free shipping for a specific category",{"type":393,"attrs":1502,"content":1503},{"textAlign":59},[1504],{"text":1505,"type":391},"Check if all items belong to a promotional category and offer free shipping:",{"type":653,"attrs":1507,"content":1508},{"class":59},[1509],{"text":1510,"type":391},"const items = cart['_embedded']['fx:items'];\nconst country = cart['_embedded']['fx:shipment']['country'];\n\nconst allPromo = items.every(item => item['_embedded']['fx:item_category']['code'] === 'promo');\n\nif (allPromo && country === 'US') {\n  rates.hide();\n  rates.add(10001, 0, '', 'Free Promotional Shipping');\n} else {\n  if (!rates.exists()) {\n    rates.add(10001, 7.99, 'Shipping', 'Standard');\n  }\n}",{"type":385,"attrs":1512,"content":1513},{"level":387,"textAlign":59},[1514],{"text":1515,"type":391},"Free domestic shipping, paid international",{"type":393,"attrs":1517,"content":1518},{"textAlign":59},[1519],{"text":1520,"type":391},"Combine a domestic free shipping threshold with separate international rates:",{"type":653,"attrs":1522,"content":1523},{"class":59},[1524],{"text":1525,"type":391},"const country = cart['_embedded']['fx:shipment']['country'];\nconst totalPrice = cart['_embedded']['fx:shipment']['total_item_price'];\n\nif (country === 'US') {\n  if (totalPrice >= 50) {\n    rates.add(10001, 0, '', 'Free Shipping');\n  } else {\n    rates.add(10001, 5.99, 'Shipping', 'Standard');\n  }\n  rates.add(10002, 14.99, 'Shipping', 'Express');\n} else {\n  rates.add(10003, 19.99, 'Shipping', 'International Standard');\n  rates.add(10004, 34.99, 'Shipping', 'International Express');\n}",{"type":385,"attrs":1527,"content":1528},{"level":387,"textAlign":59},[1529],{"text":1530,"type":391},"Percentage markup on carrier rates",{"type":393,"attrs":1532,"content":1533},{"textAlign":59},[1534],{"text":1535,"type":391},"Apply a markup to rates from a specific carrier:",{"type":653,"attrs":1537,"content":1538},{"class":59},[1539],{"text":1540,"type":391},"\u002F\u002F 15% markup on all USPS rates\nrates.filter('USPS').price('*1.15');\n\n\u002F\u002F Flat $3 surcharge on FedEx only\nrates.filter('FedEx').price('+3');",{"type":385,"attrs":1542,"content":1543},{"level":387,"textAlign":59},[1544],{"text":1545,"type":391},"Discount specific carrier services",{"type":653,"attrs":1547,"content":1548},{"class":59},[1549],{"text":1550,"type":391},"\u002F\u002F 20% discount on ground shipping\nrates.filter('Ground').price('*0.8');\n\n\u002F\u002F Subtract $2 from Priority Mail\nrates.filter('USPS Priority').price('-2');",{"type":385,"attrs":1552,"content":1553},{"level":387,"textAlign":59},[1554],{"text":1555,"type":391},"Hide specific carrier services",{"type":653,"attrs":1557,"content":1558},{"class":59},[1559],{"text":1560,"type":391},"\u002F\u002F Hide all FedEx rates\nrates.filter('FedEx').hide();\n\n\u002F\u002F Hide express and overnight options\nrates.filter('Express').hide();\nrates.filter('Overnight').hide();",{"type":385,"attrs":1562,"content":1563},{"level":387,"textAlign":59},[1564],{"text":1565,"type":391},"Hide expensive rates by price",{"type":393,"attrs":1567,"content":1568},{"textAlign":59},[1569],{"text":1570,"type":391},"Filter out any rate above a threshold:",{"type":653,"attrs":1572,"content":1573},{"class":59},[1574],{"text":1575,"type":391},"rates.filter('FedEx').each(function() {\n  if (this.price() > 100) {\n    this.hide();\n  }\n});",{"type":385,"attrs":1577,"content":1578},{"level":387,"textAlign":59},[1579],{"text":1580,"type":391},"Hide rates by state or region",{"type":393,"attrs":1582,"content":1583},{"textAlign":59},[1584],{"text":1585,"type":391},"Restrict certain shipping methods based on the customer's state or region. This example hides express and overnight options for non contiguous US states, but the same pattern works for any region based rule:",{"type":653,"attrs":1587,"content":1588},{"class":59},[1589],{"text":1590,"type":391},"const contiguous = [\n  'AL','AZ','AR','CA','CO','CT','DE','FL','GA','ID','IL','IN','IA','KS',\n  'KY','LA','ME','MD','MA','MI','MN','MS','MO','MT','NE','NV','NH','NJ',\n  'NM','NY','NC','ND','OH','OK','OR','PA','RI','SC','SD','TN','TX','UT',\n  'VT','VA','WA','WV','WI','WY','DC'\n];\n\nconst country = cart['_embedded']['fx:shipment']['country'];\nconst region = cart['_embedded']['fx:shipment']['region'];\n\nif (country === 'US' && !contiguous.includes(region)) {\n  rates.filter('Express').hide();\n  rates.filter('Overnight').hide();\n}",{"type":385,"attrs":1592,"content":1593},{"level":387,"textAlign":59},[1594],{"text":1595,"type":391},"Restrict shipping methods by category",{"type":393,"attrs":1597,"content":1598},{"textAlign":59},[1599],{"text":1600,"type":391},"If certain product categories require specific shipping methods (for example, perishable items that must ship express), hide the methods that don't apply:",{"type":653,"attrs":1602,"content":1603},{"class":59},[1604],{"text":1605,"type":391},"const items = cart['_embedded']['fx:items'];\nconst hasPerishable = items.some(item =>\n  item['_embedded']['fx:item_category']['code'] === 'perishable'\n);\n\nif (hasPerishable) {\n  rates.filter('Ground').hide();\n  rates.filter('Standard').hide();\n\n  if (!rates.exists('Express')) {\n    rates.add(10001, 24.99, 'Express Shipping', 'Required for Perishable Items');\n  }\n}",{"type":385,"attrs":1607,"content":1608},{"level":387,"textAlign":59},[1609],{"text":1610,"type":391},"Restrict shipping methods by item option",{"type":393,"attrs":1612,"content":1613},{"textAlign":59},[1614],{"text":1615,"type":391},"If products carry an option flag (for example, a \"type\" option set to \"hazmat\"), restrict which shipping methods are available:",{"type":653,"attrs":1617,"content":1618},{"class":59},[1619],{"text":1620,"type":391},"let hasHazmat = false;\nfor (const item of cart['_embedded']['fx:items']) {\n  for (const option of (item['_embedded']['fx:item_options'] || [])) {\n    if (option['name'] === 'type' && option['value'].toLowerCase() === 'hazmat') {\n      hasHazmat = true;\n    }\n  }\n}\n\nif (hasHazmat) {\n  rates.hide();\n  rates.filter('Ground').show();\n  rates.filter('Home Delivery').show();\n}",{"type":385,"attrs":1622,"content":1623},{"level":387,"textAlign":59},[1624],{"text":1625,"type":391},"Click and collect \u002F in store pickup",{"type":393,"attrs":1627,"content":1628},{"textAlign":59},[1629],{"text":1630,"type":391},"Always offer pickup, plus delivery with a free threshold:",{"type":653,"attrs":1632,"content":1633},{"class":59},[1634],{"text":1635,"type":391},"rates.add(10001, 0, '', 'Pickup From Store');\n\nconst totalPrice = cart['_embedded']['fx:shipment']['total_item_price'];\nif (totalPrice >= 50) {\n  rates.add(10002, 0, '', 'Free Delivery');\n} else {\n  rates.add(10002, 7.99, '', 'Standard Delivery');\n}",{"type":385,"attrs":1637,"content":1638},{"level":387,"textAlign":59},[1639],{"text":1640,"type":391},"Postal code zone based local delivery",{"type":393,"attrs":1642,"content":1643},{"textAlign":59},[1644],{"text":1645,"type":391},"Define ZIP code zones for free, paid, or pickup only delivery:",{"type":653,"attrs":1647,"content":1648},{"class":59},[1649],{"text":1650,"type":391},"const postalCode = Number(cart['_embedded']['fx:shipment']['postal_code']);\nconst country = cart['_embedded']['fx:shipment']['country'];\n\nconst localDeliveryZips = [80001, 80002, 80003, 80004, 80005];\nconst extendedDeliveryZips = [80023, 80026, 80027, 80301, 80302];\n\nif (country === 'US') {\n  if (localDeliveryZips.includes(postalCode)) {\n    rates.add(10001, 0, '', 'Free Local Delivery');\n  }\n  if (extendedDeliveryZips.includes(postalCode)) {\n    rates.add(10002, 5, '', 'Extended Delivery');\n  }\n  \u002F\u002F Always offer pickup\n  rates.add(10003, 0, '', 'In Store Pickup');\n}",{"type":385,"attrs":1652,"content":1653},{"level":387,"textAlign":59},[1654],{"text":1655,"type":391},"Local delivery by postal code prefix",{"type":393,"attrs":1657,"content":1658},{"textAlign":59},[1659],{"text":1660,"type":391},"Use the first few characters of the postal code to define local delivery zones. This works for any country with alphanumeric postal codes (Canada, UK, etc.):",{"type":653,"attrs":1662,"content":1663},{"class":59},[1664],{"text":1665,"type":391},"const freeDeliveryPrefixes = ['L5H', 'L4T', 'L4W', 'L4X', 'L4Y', 'L4Z', 'L5A', 'L5B'];\nconst postcode = cart['_embedded']['fx:shipment']['postal_code'].toUpperCase().substring(0, 3);\nconst orderTotal = cart['_embedded']['fx:shipment']['total_item_price'];\n\nif (freeDeliveryPrefixes.includes(postcode) && orderTotal > 200) {\n  rates.add(10001, 0, '', 'Free Local Delivery');\n}",{"type":385,"attrs":1667,"content":1668},{"level":387,"textAlign":59},[1669],{"text":1670,"type":391},"Adjust rates based on a custom field",{"type":393,"attrs":1672,"content":1673},{"textAlign":59},[1674,1676,1680],{"text":1675,"type":391},"Read a custom checkout field (added with ",{"text":1677,"type":391,"marks":1678},"data-fc-shipping-custom-field",[1679],{"type":614},{"text":1681,"type":391},") and modify rates accordingly. This example adds shipping insurance as a percentage of the cart total when the customer checks a box:",{"type":653,"attrs":1683,"content":1684},{"class":59},[1685],{"text":1686,"type":391},"const cartTotal = cart['_embedded']['fx:shipment']['total_item_price'];\nlet addInsurance = false;\n\nfor (const field of (cart['_embedded']['fx:custom_fields'] || [])) {\n  if (field['name'] === 'add_insurance') {\n    addInsurance = true;\n  }\n}\n\nif (addInsurance) {\n  const insuranceAmount = cartTotal * 0.01;\n  rates.each(function() {\n    this.price('+' + insuranceAmount)\n        .service(this.service() + ' (incl. insurance)');\n  });\n}",{"type":385,"attrs":1688,"content":1689},{"level":387,"textAlign":59},[1690],{"text":1691,"type":391},"Paid shipping upgrade alongside free shipping",{"type":393,"attrs":1693,"content":1694},{"textAlign":59},[1695],{"text":1696,"type":391},"Offer a free base option while keeping a paid upgrade available (for example, a signature required variant at just the surcharge price):",{"type":653,"attrs":1698,"content":1699},{"class":59},[1700],{"text":1701,"type":391},"const country = cart['_embedded']['fx:shipment']['country'];\nconst totalPrice = cart['_embedded']['fx:shipment']['total_item_price'];\n\nif (rates.exists('UPS Ground')) {\n  const upsPrice = rates.filter('UPS Ground').price();\n  rates.add(10002, upsPrice + 5.50, 'UPS', 'Ground with Signature Required');\n}\nif (rates.exists('FedEx Home Delivery')) {\n  const fedexPrice = rates.filter('FedEx Home Delivery').price();\n  rates.add(10001, fedexPrice + 6.70, 'FedEx', 'Home Delivery with Signature Required');\n}\n\nif (totalPrice >= 200 && country === 'US') {\n  rates.hide();\n  rates.add(11000, 0, '', 'Free Shipping');\n  rates.filter(10002).price(5.50).show();\n  rates.filter(10001).price(6.70).show();\n}",{"type":385,"attrs":1703,"content":1704},{"level":387,"textAlign":59},[1705],{"text":1706,"type":391},"Require a custom quote for heavy orders",{"type":653,"attrs":1708,"content":1709},{"class":59},[1710],{"text":1711,"type":391},"const totalWeight = cart['_embedded']['fx:shipment']['total_weight'];\n\nif (totalWeight > 50) {\n  rates.error('Orders over 50kg require a custom shipping quote. Please contact us.');\n}",{"type":385,"attrs":1713,"content":1714},{"level":387,"textAlign":59},[1715],{"text":1716,"type":391},"Distance based shipping with Google Maps",{"type":393,"attrs":1718,"content":1719},{"textAlign":59},[1720,1722,1726],{"text":1721,"type":391},"Use ",{"text":1723,"type":391,"marks":1724},"await request()",[1725],{"type":614},{"text":1727,"type":391}," to call the Google Maps Distance Matrix API and set rates based on distance from your store:",{"type":653,"attrs":1729,"content":1730},{"class":59},[1731],{"text":1732,"type":391},"const google_maps_api_key = 'YOUR_API_KEY';\nconst origin_address = '123 Main St, City, STATE, Country, 12345';\nconst unit_type = 'imperial'; \u002F\u002F 'metric' or 'imperial'\n\nconst shipment = cart['_embedded']['fx:shipment'];\nlet address1 = '';\nfor (const c of (cart['_embedded']['fx:custom_fields'] || [])) {\n  if (c['name'] === 'shipping_address1') {\n    address1 = c['value'];\n    break;\n  }\n}\n\nconst customer_address = [address1, shipment['city'], shipment['region'],\n    shipment['country'], shipment['postal_code']].join(', ');\n\nconst maps_url = 'https:\u002F\u002Fmaps.googleapis.com\u002Fmaps\u002Fapi\u002Fdistancematrix\u002Fjson'\n    + '?origins=' + encodeURIComponent(origin_address)\n    + '&destinations=' + encodeURIComponent(customer_address)\n    + '&units=' + unit_type\n    + '&key=' + google_maps_api_key;\n\nlet distance = -1;\nawait request(maps_url, function(error, response, body) {\n  const payload = JSON.parse(body);\n  if (response && response.statusCode === 200\n      && payload.status === 'OK'\n      && payload.rows[0].elements[0].status === 'OK') {\n    distance = payload.rows[0].elements[0].distance.value;\n    distance = (unit_type === 'metric') ? distance \u002F 1000 : distance \u002F 1609.34;\n  }\n});\n\nif (distance > 60) {\n  rates.error('Sorry, you are too far away for delivery.');\n} else if (distance > -1) {\n  let shipping = 0;\n  if (distance > 25) shipping = 5;\n  if (distance > 40) shipping = 10;\n  rates.add(10001, shipping, '', 'Local Delivery');\n\n  if (shipment['total_item_price'] >= 150) {\n    rates.filter(10001).price(0).service('Free Delivery');\n  }\n} else {\n  rates.error(\"Sorry, we're unable to calculate delivery to your address.\");\n}\n\nrates.add(10000, 0, '', 'Pickup From Store');",{"type":385,"attrs":1734,"content":1735},{"level":387,"textAlign":59},[1736],{"text":1737,"type":391},"External carrier API (EasyPost)",{"type":393,"attrs":1739,"content":1740},{"textAlign":59},[1741,1742,1745],{"text":1721,"type":391},{"text":1723,"type":391,"marks":1743},[1744],{"type":614},{"text":1746,"type":391}," to get multi carrier rates from EasyPost:",{"type":653,"attrs":1748,"content":1749},{"class":59},[1750],{"text":1751,"type":391},"const easypostApiKey = 'YOUR_EASYPOST_KEY';\nconst shipment = cart['_embedded']['fx:shipment'];\n\nconst shipmentData =\n  'shipment[to_address][name]=' + shipment['first_name'] + ' ' + shipment['last_name'] +\n  '&shipment[to_address][street1]=' + shipment['address1'] +\n  '&shipment[to_address][city]=' + shipment['city'] +\n  '&shipment[to_address][state]=' + shipment['region'] +\n  '&shipment[to_address][zip]=' + shipment['postal_code'] +\n  '&shipment[to_address][country]=' + shipment['country'] +\n  '&shipment[from_address][state]=' + shipment['origin_region'] +\n  '&shipment[from_address][zip]=' + shipment['origin_postal_code'] +\n  '&shipment[from_address][country]=' + shipment['origin_country'] +\n  '&shipment[parcel][length]=5&shipment[parcel][width]=5&shipment[parcel][height]=5' +\n  '&shipment[parcel][weight]=' + (shipment['total_weight'] * 16); \u002F\u002F lbs to oz\n\ntry {\n  await request({\n    url: 'https:\u002F\u002Fapi.easypost.com\u002Fv2\u002Fshipments',\n    method: 'POST',\n    body: shipmentData,\n    auth: { 'user': easypostApiKey }\n  }, function(error, response, body) {\n    const payload = JSON.parse(body);\n    for (let i = 0; i \u003C payload.rates.length; i++) {\n      rates.add(10000 + i, payload.rates[i]['rate'],\n          payload.rates[i]['carrier'], payload.rates[i]['service']);\n    }\n  });\n} catch (e) {\n  rates.error(\"Sorry, we're unable to get shipping rates. Please try again or contact us.\");\n}",{"type":385,"attrs":1753,"content":1754},{"level":387,"textAlign":59},[1755],{"text":1756,"type":391},"Full combined example",{"type":393,"attrs":1758,"content":1759},{"textAlign":59},[1760],{"text":1761,"type":391},"A more complete example that ties multiple patterns together (carrier markup, free shipping by coupon and threshold, non contiguous US restrictions, and fallback rates):",{"type":653,"attrs":1763,"content":1764},{"class":59},[1765],{"text":1766,"type":391},"const shipment = cart['_embedded']['fx:shipment'];\nconst country = shipment['country'];\nconst region = shipment['region'];\nconst totalPrice = shipment['total_item_price'];\nconst discounts = cart['_embedded']['fx:discounts'] || [];\n\nconst contiguous = [\n  'AL','AZ','AR','CA','CO','CT','DE','FL','GA','ID','IL','IN','IA','KS',\n  'KY','LA','ME','MD','MA','MI','MN','MS','MO','MT','NE','NV','NH','NJ',\n  'NM','NY','NC','ND','OH','OK','OR','PA','RI','SC','SD','TN','TX','UT',\n  'VT','VA','WA','WV','WI','WY','DC'\n];\n\nconst hasFreeShipCoupon = discounts.some(d =>\n  d['code'] === 'freeshipping' || d['code'].endsWith('-fs')\n);\n\n\u002F\u002F Apply 10% markup to carrier rates and clean up labels\nif (rates.exists()) {\n  rates.price('*1.10');\n\n  if (country === 'US' && !contiguous.includes(region)) {\n    rates.filter('Overnight').hide();\n    rates.filter('Express').hide();\n  }\n}\n\n\u002F\u002F Free shipping logic\nif (hasFreeShipCoupon && country === 'US') {\n  rates.hide();\n  rates.add(10001, 0, '', 'Free Shipping (Coupon)');\n} else if (country === 'US' && totalPrice >= 75) {\n  rates.add(10001, 0, '', 'Free Standard Shipping');\n}\n\n\u002F\u002F Fallback if no rates at all\nif (!rates.exists()) {\n  if (country === 'US') {\n    rates.add(10090, 7.99, 'Shipping', 'Standard');\n    rates.add(10091, 14.99, 'Shipping', 'Express');\n  } else if (country === 'CA' || country === 'MX') {\n    rates.add(10092, 14.99, 'Shipping', 'North America Standard');\n  } else {\n    rates.add(10093, 24.99, 'Shipping', 'International Standard');\n  }\n}",{"id":59,"alt":59,"name":13,"focus":59,"title":59,"source":59,"filename":13,"copyright":59,"fieldtype":81,"meta_data":1768},{},"Ready to use code snippets to get started with your Custom Shipping Code.",[],"custom-shipping-code-examples","help\u002Farticles\u002Fcustom-shipping-code-examples",-1910,[],"cd513ab9-1f04-453c-8401-4df4e3694d3e",[],{"name":1778,"created_at":1779,"published_at":1780,"updated_at":1781,"id":1782,"uuid":404,"content":1783,"slug":2030,"full_slug":2031,"sort_by_date":59,"position":2032,"tag_list":2033,"is_startpage":24,"parent_id":588,"meta_data":59,"group_id":2034,"first_published_at":2035,"release_id":59,"lang":65,"path":59,"alternates":2036,"default_full_slug":59,"translated_slugs":59},"Custom Shipping Code Overview","2026-05-27T21:02:51.076Z","2026-06-03T20:57:52.434Z","2026-06-03T20:57:52.448Z",181150396796756,{"_uid":1784,"body":1785,"name":1778,"image":2025,"pinned":24,"summary":2027,"category":320,"component":266,"related_articles":2028},"e6c68309-9708-4ad7-aad1-c60e94e17334",{"type":382,"content":1786},[1787,1791,1796,1801,1806,1811,1827,1832,1854,1859,1864,1869,1891,1896,1968,1973,1987,1991,1996,2001],{"type":385,"attrs":1788,"content":1789},{"level":387,"textAlign":59},[1790],{"text":390,"type":391},{"type":393,"attrs":1792,"content":1793},{"textAlign":59},[1794],{"text":1795,"type":391},"Custom Shipping Code lets you enter JavaScript directly into your store's Foxy admin to control shipping rates. The code runs server side (Node.js) after all carrier rates and custom endpoint results have been collected, giving you the ability to add new rates, modify prices, rename services, hide or show rates, and return errors — all without hosting your own server.",{"type":385,"attrs":1797,"content":1798},{"level":387,"textAlign":59},[1799],{"text":1800,"type":391},"How to enable",{"type":393,"attrs":1802,"content":1803},{"textAlign":59},[1804],{"text":1805,"type":391},"In your store's Shipping page, click Custom Shipping Code in the Shipping methods list, paste your code into the editor, and click Create, then Save. For a full walkthrough with each step, see [Add Custom Shipping Code].",{"type":393,"attrs":1807,"content":1808},{"textAlign":59},[1809],{"text":1810,"type":391},"Two things to set up alongside your code:",{"type":541,"content":1812},[1813,1820],{"type":438,"content":1814},[1815],{"type":393,"attrs":1816,"content":1817},{"textAlign":59},[1818],{"text":1819,"type":391},"Enable \"Prevent shipping rate tampering\" (recommended) unless you have legacy browser side JavaScript that modifies rates.",{"type":438,"content":1821},[1822],{"type":393,"attrs":1823,"content":1824},{"textAlign":59},[1825],{"text":1826,"type":391},"Make sure any categories that should use custom code have their delivery type set to \"Shipped using live shipping rates\" with a default weight configured.",{"type":385,"attrs":1828,"content":1829},{"level":387,"textAlign":59},[1830],{"text":1831,"type":391},"Runtime environment",{"type":393,"attrs":1833,"content":1834},{"textAlign":59},[1835,1837,1841,1843,1847,1849,1852],{"text":1836,"type":391},"Your code runs in a Node.js environment (server side, UTC timezone) with access to a set of pre installed Node modules. The code is isolated per store. ",{"text":1838,"type":391,"marks":1839},"async",[1840],{"type":614},{"text":1842,"type":391},"\u002F",{"text":1844,"type":391,"marks":1845},"await",[1846],{"type":614},{"text":1848,"type":391}," is supported for making external requests (for example, to query a third party API like Shippo). Note: the code editor's validation may show warnings on lines containing ",{"text":1844,"type":391,"marks":1850},[1851],{"type":614},{"text":1853,"type":391},"; you can safely ignore these.",{"type":393,"attrs":1855,"content":1856},{"textAlign":59},[1857],{"text":1858,"type":391},"When you update your code, Foxy redeploys it behind the scenes. The Node.js version may be updated during redeployment, so avoid relying on version specific behavior.",{"type":385,"attrs":1860,"content":1861},{"level":387,"textAlign":59},[1862],{"text":1863,"type":391},"Available globals",{"type":393,"attrs":1865,"content":1866},{"textAlign":59},[1867],{"text":1868,"type":391},"Two objects are available in your code environment:",{"type":541,"content":1870},[1871,1881],{"type":438,"content":1872},[1873],{"type":393,"attrs":1874,"content":1875},{"textAlign":59},[1876,1879],{"text":611,"type":391,"marks":1877},[1878],{"type":614},{"text":1880,"type":391}," — the rates collection, pre populated with any rates returned from carriers or the custom endpoint. This is the entry point to the Shipping API. See the [Custom Shipping Code API Reference] for the full method list.",{"type":438,"content":1882},[1883],{"type":393,"attrs":1884,"content":1885},{"textAlign":59},[1886,1889],{"text":1178,"type":391,"marks":1887},[1888],{"type":614},{"text":1890,"type":391}," — the same payload object that the Custom Shipping Endpoint receives. See the [Shipping Payload Reference] for the full structure.",{"type":393,"attrs":1892,"content":1893},{"textAlign":59},[1894],{"text":1895,"type":391},"A few Node modules are also available Node:",{"type":541,"content":1897},[1898,1918,1935,1952],{"type":438,"content":1899},[1900],{"type":393,"attrs":1901,"content":1902},{"textAlign":59},[1903,1910,1912,1916],{"text":1904,"type":391,"marks":1905},"node-fetch",[1906],{"type":401,"attrs":1907},{"href":1908,"uuid":59,"anchor":59,"target":1909,"linktype":31},"https:\u002F\u002Fgithub.com\u002Fnode-fetch\u002Fnode-fetch","_blank",{"text":1911,"type":391}," (available as ",{"text":1913,"type":391,"marks":1914},"fetch",[1915],{"type":614},{"text":1917,"type":391},")",{"type":438,"content":1919},[1920],{"type":393,"attrs":1921,"content":1922},{"textAlign":59},[1923,1929,1930,1934],{"text":1924,"type":391,"marks":1925},"Foxy SDK",[1926],{"type":401,"attrs":1927},{"href":1928,"uuid":59,"anchor":59,"target":1909,"linktype":31},"https:\u002F\u002Fsdk.foxy.dev\u002F",{"text":1911,"type":391},{"text":1931,"type":391,"marks":1932},"FoxySDK",[1933],{"type":614},{"text":1917,"type":391},{"type":438,"content":1936},[1937],{"type":393,"attrs":1938,"content":1939},{"textAlign":59},[1940,1946,1947,1951],{"text":1941,"type":391,"marks":1942},"Shippo",[1943],{"type":401,"attrs":1944},{"href":1945,"uuid":59,"anchor":59,"target":1909,"linktype":31},"https:\u002F\u002Fgithub.com\u002Fgoshippo\u002Fshippo-node-client",{"text":1911,"type":391},{"text":1948,"type":391,"marks":1949},"shippo",[1950],{"type":614},{"text":1917,"type":391},{"type":438,"content":1953},[1954],{"type":393,"attrs":1955,"content":1956},{"textAlign":59},[1957,1963,1964,1967],{"text":1958,"type":391,"marks":1959},"xml2js",[1960],{"type":401,"attrs":1961},{"href":1962,"uuid":59,"anchor":59,"target":1909,"linktype":31},"https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002Fxml2js",{"text":1911,"type":391},{"text":1958,"type":391,"marks":1965},[1966],{"type":614},{"text":1917,"type":391},{"type":385,"attrs":1969,"content":1970},{"level":387,"textAlign":59},[1971],{"text":1972,"type":391},"Examples",{"type":393,"attrs":1974,"content":1975},{"textAlign":59},[1976,1978,1981,1982,1985],{"text":1977,"type":391},"Here's a quick example to show how the ",{"text":611,"type":391,"marks":1979},[1980],{"type":614},{"text":720,"type":391},{"text":1178,"type":391,"marks":1983},[1984],{"type":614},{"text":1986,"type":391}," objects work together. This adds two rates and makes the standard option free when the cart total hits $40:",{"type":653,"attrs":1988,"content":1989},{"class":59},[1990],{"text":1255,"type":391},{"type":393,"attrs":1992,"content":1993},{"textAlign":59},[1994],{"text":1995,"type":391},"For many more ready to use examples (tiered rates, weight based pricing, coupon triggered free shipping, country tiers, label cleanup, and more), see [Custom Shipping Code Examples].",{"type":385,"attrs":1997,"content":1998},{"level":387,"textAlign":59},[1999],{"text":2000,"type":391},"Migrating from legacy footer snippets",{"type":393,"attrs":2002,"content":2003},{"textAlign":59},[2004,2006,2010,2011,2015,2017,2023],{"text":2005,"type":391},"If your store currently uses the older ",{"text":2007,"type":391,"marks":2008},"FC.customFlatRates",[2009],{"type":614},{"text":645,"type":391},{"text":2012,"type":391,"marks":2013},"FC.customLiveShipping",[2014],{"type":614},{"text":2016,"type":391}," browser side snippets, migrating to Custom Shipping Code is recommended. The legacy snippets don't work with subscription renewals (which run server side) and aren't compatible with shipping rate signing. See the ",{"text":2018,"type":391,"marks":2019},"migration guide on the wiki",[2020],{"type":401,"attrs":2021},{"href":2022,"uuid":59,"anchor":59,"target":59,"linktype":31},"https:\u002F\u002Fwiki.foxycart.com\u002Fv\u002F2.0\u002Fshipping\u002Fcustom_code\u002Fmigrating",{"text":2024,"type":391}," for a function by function mapping.",{"id":59,"alt":59,"name":13,"focus":59,"title":59,"source":59,"filename":13,"copyright":59,"fieldtype":81,"meta_data":2026},{},"Write JavaScript in the Foxy admin to add, modify, or remove shipping rates.",[583,414,2029],"e1c530e9-f90b-4e2b-8bee-9cffc70c9e68","custom-shipping-code-overview","help\u002Farticles\u002Fcustom-shipping-code-overview",-1890,[],"b249d669-6829-47c7-8a4a-bd2bf9f197f2","2026-05-28T21:09:22.756Z",[],{"name":2038,"created_at":2039,"published_at":2040,"updated_at":2041,"id":2042,"uuid":2043,"content":2044,"slug":2196,"full_slug":2197,"sort_by_date":59,"position":2198,"tag_list":2199,"is_startpage":24,"parent_id":588,"meta_data":59,"group_id":2200,"first_published_at":2040,"release_id":59,"lang":65,"path":59,"alternates":2201,"default_full_slug":59,"translated_slugs":59},"Get Live Shipping Rates with EasyPost","2026-06-08T20:59:54.662Z","2026-06-24T15:27:12.931Z","2026-06-24T15:27:12.954Z",185396406994079,"0e70be55-4323-4cee-a77d-a787183b35e2",{"_uid":2045,"body":2046,"name":2038,"image":2192,"pinned":24,"summary":2194,"category":320,"component":266,"related_articles":2195},"d7dd9f7a-cc86-4701-978f-e20a5d66c90d",{"type":382,"content":2047},[2048,2052,2057,2062,2067,2097,2102,2107,2112,2117,2161,2166,2179],{"type":385,"attrs":2049,"content":2050},{"level":387,"textAlign":59},[2051],{"text":390,"type":391},{"type":393,"attrs":2053,"content":2054},{"textAlign":59},[2055],{"text":2056,"type":391},"EasyPost is a multi carrier shipping API that returns rates from a wide range of carriers through one integration. If you need rates beyond Foxy's native carriers (USPS, UPS, FedEx), you can fetch them from your EasyPost account using Foxy's Custom Shipping Code feature. This article shows you the code to connect to EasyPost and how to install it on your store.",{"type":385,"attrs":2058,"content":2059},{"level":387,"textAlign":59},[2060],{"text":2061,"type":391},"Before You Start",{"type":393,"attrs":2063,"content":2064},{"textAlign":59},[2065],{"text":2066,"type":391},"You will need:",{"type":541,"content":2068},[2069,2076,2083,2090],{"type":438,"content":2070},[2071],{"type":393,"attrs":2072,"content":2073},{"textAlign":59},[2074],{"text":2075,"type":391},"An EasyPost account with an API key (EasyPost dashboard, under Account Settings > API Keys). Use your production key for live rates.",{"type":438,"content":2077},[2078],{"type":393,"attrs":2079,"content":2080},{"textAlign":59},[2081],{"text":2082,"type":391},"Carriers added to your EasyPost account. By default EasyPost returns USPS rates; add more carriers in the EasyPost dashboard to get more rates.",{"type":438,"content":2084},[2085],{"type":393,"attrs":2086,"content":2087},{"textAlign":59},[2088],{"text":2089,"type":391},"Custom Shipping Code enabled on your store. See [Add Custom Shipping Code].",{"type":438,"content":2091},[2092],{"type":393,"attrs":2093,"content":2094},{"textAlign":59},[2095],{"text":2096,"type":391},"At least one product category set to a delivery type of \"Shipped using live shipping rates\". See [Shipping and Categories].",{"type":385,"attrs":2098,"content":2099},{"level":387,"textAlign":59},[2100],{"text":2101,"type":391},"The Shipping Code",{"type":393,"attrs":2103,"content":2104},{"textAlign":59},[2105],{"text":2106,"type":391},"This code builds a shipment from the cart payload, posts it to the EasyPost shipments endpoint, then adds each returned rate to the cart. EasyPost expects weight in ounces, so the code converts the cart's weight from pounds.",{"type":653,"attrs":2108,"content":2109},{"class":59},[2110],{"text":2111,"type":391},"const easypostApiKey = 'YOUR_EASYPOST_KEY';\nconst shipment = cart['_embedded']['fx:shipment'];\n\nconst shipmentData =\n  'shipment[to_address][name]=' + shipment['first_name'] + ' ' + shipment['last_name'] +\n  '&shipment[to_address][street1]=' + shipment['address1'] +\n  '&shipment[to_address][city]=' + shipment['city'] +\n  '&shipment[to_address][state]=' + shipment['region'] +\n  '&shipment[to_address][zip]=' + shipment['postal_code'] +\n  '&shipment[to_address][country]=' + shipment['country'] +\n  '&shipment[from_address][state]=' + shipment['origin_region'] +\n  '&shipment[from_address][zip]=' + shipment['origin_postal_code'] +\n  '&shipment[from_address][country]=' + shipment['origin_country'] +\n  '&shipment[parcel][length]=5&shipment[parcel][width]=5&shipment[parcel][height]=5' +\n  '&shipment[parcel][weight]=' + (shipment['total_weight'] * 16); \u002F\u002F lbs to oz\n\ntry {\n  await request({\n    url: 'https:\u002F\u002Fapi.easypost.com\u002Fv2\u002Fshipments',\n    method: 'POST',\n    body: shipmentData,\n    auth: { 'user': easypostApiKey }\n  }, function (error, response, body) {\n    const payload = JSON.parse(body);\n    for (let i = 0; i \u003C payload.rates.length; i++) {\n      rates.add(\n        10000 + i,\n        payload.rates[i]['rate'],\n        payload.rates[i]['carrier'],\n        payload.rates[i]['service']\n      );\n    }\n  });\n} catch (e) {\n  rates.error(\"Sorry, we're unable to get shipping rates. Please try again or contact us.\");\n}",{"type":385,"attrs":2113,"content":2114},{"level":387,"textAlign":59},[2115],{"text":2116,"type":391},"Install the Integration",{"type":433,"attrs":2118,"content":2119},{"order":435},[2120,2127,2134,2147,2154],{"type":438,"content":2121},[2122],{"type":393,"attrs":2123,"content":2124},{"textAlign":59},[2125],{"text":2126,"type":391},"In your EasyPost dashboard, go to Account Settings > API Keys and copy your production API key.",{"type":438,"content":2128},[2129],{"type":393,"attrs":2130,"content":2131},{"textAlign":59},[2132],{"text":2133,"type":391},"In the Foxy admin (admin.foxy.io), open the shipping settings for your store and paste the code above into the Custom Shipping Code editor.",{"type":438,"content":2135},[2136],{"type":393,"attrs":2137,"content":2138},{"textAlign":59},[2139,2141,2145],{"text":2140,"type":391},"Replace ",{"text":2142,"type":391,"marks":2143},"YOUR_EASYPOST_KEY",[2144],{"type":614},{"text":2146,"type":391}," with the key you copied.",{"type":438,"content":2148},[2149],{"type":393,"attrs":2150,"content":2151},{"textAlign":59},[2152],{"text":2153,"type":391},"Save your settings. Wait roughly 15 to 20 seconds, then refresh the page. If the save was successful, you will see your code again after refreshing.",{"type":438,"content":2155},[2156],{"type":393,"attrs":2157,"content":2158},{"textAlign":59},[2159],{"text":2160,"type":391},"Test it. Add a product from a live rate shippable category to your cart, then enter a shipping address on the cart or checkout. You should see rates returning from your EasyPost account.",{"type":385,"attrs":2162,"content":2163},{"level":387,"textAlign":59},[2164],{"text":2165,"type":391},"Customize the Integration",{"type":393,"attrs":2167,"content":2168},{"textAlign":59},[2169,2171,2177],{"text":2170,"type":391},"This is a basic setup. It uses default parcel dimensions (a 5 by 5 by 5 inch box) and returns every rate EasyPost provides. You can adjust the parcel, restrict which carriers are rated (by passing carrier accounts in the request), or work with the returned rates further. See the EasyPost documentation on shipments and rates to extend the request, and the Custom ",{"text":2172,"type":391,"marks":2173},"Shipping Code API Reference",[2174],{"type":401,"attrs":2175},{"href":2176,"uuid":583,"anchor":59,"target":405,"linktype":14},"\u002Fhelp\u002Farticles\u002Fcustom-shipping-code-api-reference",{"text":2178,"type":391}," to filter, rename, or reprice rates.",{"type":393,"attrs":2180,"content":2181},{"textAlign":59},[2182,2184,2191],{"text":2183,"type":391},"Rates from custom shipping code are not currency converted by Foxy. If your store uses a non USD currency, set the rate values in the cart's currency yourself. See ",{"text":2185,"type":391,"marks":2186},"Shipping Currency Conversion",[2187],{"type":401,"attrs":2188},{"href":2189,"uuid":2190,"anchor":59,"target":405,"linktype":14},"\u002Fhelp\u002Farticles\u002Fshipping-currency-conversion","7c7777a7-e9ec-4bec-8321-501eb979d2d7",{"text":416,"type":391},{"id":59,"alt":59,"name":13,"focus":59,"title":59,"source":59,"filename":13,"copyright":59,"fieldtype":81,"meta_data":2193},{},"Connect your EasyPost account to your Foxy store with the Custom Shipping Code feature to fetch live multi carrier rates at checkout.",[404,378],"get-live-shipping-rates-with-easypost","help\u002Farticles\u002Fget-live-shipping-rates-with-easypost",-2030,[],"d76549f7-e7dd-446f-8301-29f7aa5e2f3c",[],{"name":2203,"created_at":2204,"published_at":2205,"updated_at":2206,"id":2207,"uuid":2208,"content":2209,"slug":2416,"full_slug":2417,"sort_by_date":59,"position":2418,"tag_list":2419,"is_startpage":24,"parent_id":588,"meta_data":59,"group_id":2420,"first_published_at":2205,"release_id":59,"lang":65,"path":59,"alternates":2421,"default_full_slug":59,"translated_slugs":59},"Get Live Shipping Rates with Postmen","2026-06-08T21:12:53.444Z","2026-06-24T15:27:12.686Z","2026-06-24T15:27:12.731Z",185399596876982,"aaa21cba-6a8c-428b-9839-271c1db2453e",{"_uid":2210,"body":2211,"name":2203,"image":2412,"pinned":24,"summary":2414,"category":320,"component":266,"related_articles":2415},"b555f986-9b08-4e37-88c7-ed2a9ad8a460",{"type":382,"content":2212},[2213,2217,2222,2226,2230,2274,2278,2289,2294,2298,2387,2391,2402],{"type":385,"attrs":2214,"content":2215},{"level":387,"textAlign":59},[2216],{"text":390,"type":391},{"type":393,"attrs":2218,"content":2219},{"textAlign":59},[2220],{"text":2221,"type":391},"Postmen (by AfterShip) returns rates from multiple carriers through one API. If you need rates from carriers that Foxy does not natively support, you can fetch them from your Postmen account using Foxy's Custom Shipping Code feature. This article shows you the code to connect to Postmen and how to install it on your store.",{"type":385,"attrs":2223,"content":2224},{"level":387,"textAlign":59},[2225],{"text":2061,"type":391},{"type":393,"attrs":2227,"content":2228},{"textAlign":59},[2229],{"text":2066,"type":391},{"type":541,"content":2231},[2232,2239,2246,2259],{"type":438,"content":2233},[2234],{"type":393,"attrs":2235,"content":2236},{"textAlign":59},[2237],{"text":2238,"type":391},"A Postmen account with an API key. Postmen provides separate Production and Testing keys; pick the one that matches the environment you want.",{"type":438,"content":2240},[2241],{"type":393,"attrs":2242,"content":2243},{"textAlign":59},[2244],{"text":2245,"type":391},"One or more shipper accounts created in Postmen (Postmen dashboard, under Shipper Accounts). Make sure they belong to the same environment (Production or Testing) as your API key.",{"type":438,"content":2247},[2248],{"type":393,"attrs":2249,"content":2250},{"textAlign":59},[2251,2253,2258],{"text":2252,"type":391},"Custom Shipping Code enabled on your store. See ",{"text":373,"type":391,"marks":2254},[2255],{"type":401,"attrs":2256},{"href":2257,"uuid":378,"anchor":59,"target":405,"linktype":14},"\u002Fhelp\u002Farticles\u002Fadd-custom-shipping-code",{"text":416,"type":391},{"type":438,"content":2260},[2261],{"type":393,"attrs":2262,"content":2263},{"textAlign":59},[2264,2266,2273],{"text":2265,"type":391},"At least one product category set to a delivery type of \"Shipped using live shipping rates\". See ",{"text":2267,"type":391,"marks":2268},"Shipping and Categories",[2269],{"type":401,"attrs":2270},{"href":2271,"uuid":2272,"anchor":59,"target":405,"linktype":14},"\u002Fhelp\u002Farticles\u002Fshipping-and-categories","b7d2c21b-aa39-4e1f-aea1-4a57bb102f35",{"text":416,"type":391},{"type":385,"attrs":2275,"content":2276},{"level":387,"textAlign":59},[2277],{"text":2101,"type":391},{"type":393,"attrs":2279,"content":2280},{"textAlign":59},[2281,2283,2287],{"text":2282,"type":391},"This code builds a rate request from the cart payload, loops the cart items into the parcel, posts the request to the Postmen rates endpoint, then adds each returned rate to the cart. Postmen expects 3 letter (ISO 3166 alpha 3) country codes, so the included ",{"text":2284,"type":391,"marks":2285},"country_to_3",[2286],{"type":614},{"text":2288,"type":391}," helper converts Foxy's 2 letter codes. Set the options at the top to match your account and packaging.",{"type":653,"attrs":2290,"content":2291},{"class":59},[2292],{"text":2293,"type":391},"\u002F\u002F Set to the API key of your Postmen account\nlet api_key = 'YOUR-POSTMEN-API-KEY';\n\u002F\u002F Set to false to use test shipper accounts\nlet is_production = true;\n\u002F\u002F Shipper accounts\nlet shipper_accounts = [\n    { 'id': 'SHIPPER-ACCOUNT-ID-1' },\n    { 'id': 'SHIPPER-ACCOUNT-ID-2' }\n];\n\u002F\u002F Weight units for the store ('lb' or 'kg')\nlet weight_unit = 'lb';\n\u002F\u002F Length units for the store ('in' or 'cm')\nlet length_unit = 'in';\n\u002F\u002F Parcel dimensions\nlet parcel_width = 20,\n    parcel_height = 10,\n    parcel_depth = 10;\n\n\n\nconst shipment = cart['_embedded']['fx:shipment'];\n\nlet payload = {\n    'async': false,\n    'shipper_accounts': shipper_accounts,\n    'shipment': {\n        'parcels': [\n            {\n                'box_type': 'custom',\n                'weight': {\n                    'value': shipment['total_weight'],\n                    'unit': weight_unit\n                },\n                'dimension': {\n                    'width': parcel_width,\n                    'height': parcel_height,\n                    'depth': parcel_depth,\n                    'unit': length_unit\n                },\n                'items': [\n                    \u002F\u002F Populated below\n                ]\n            }\n        ],\n        'ship_from': {\n            'state': shipment['origin_region'],\n            'postal_code': shipment['origin_postal_code'],\n            'country': country_to_3(shipment['origin_country']),\n        },\n        'ship_to': {\n            \u002F\u002F Populated below\n            'country': country_to_3(shipment['country']),\n            'type': shipment['is_residential'] ? 'residential' : 'business'\n        }\n    },\n    'is_document': false\n};\n\n\u002F\u002F Ship to address\nif (shipment['first_name']) {\n    payload.shipment.ship_to['contact_name'] = shipment['first_name'] + \" \" + shipment['last_name'];\n}\nif (shipment['address1']) {\n    payload.shipment.ship_to['street1'] = shipment['address1'];\n}\nif (shipment['city']) {\n    payload.shipment.ship_to['city'] = shipment['city'];\n}\nif (shipment['region']) {\n    payload.shipment.ship_to['state'] = shipment['region'];\n}\nif (shipment['postal_code']) {\n    payload.shipment.ship_to['postal_code'] = shipment['postal_code'];\n}\n\n\u002F\u002F Items\nfor (let p in cart['_embedded']['fx:items']) {\n    let item = cart['_embedded']['fx:items'][p];\n\n    let item_details = {\n        'description': item.name,\n        'quantity': item.quantity,\n        'price': {\n            'amount': item.price,\n            'currency': cart.currency_code\n        },\n        'weight': {\n            'value': item.weight,\n            'unit': weight_unit\n        }\n    }\n\n    if (item.sku) {\n        item_details['sku'] = item.code\n    }\n\n    payload.shipment.parcels[0].items.push(item_details);\n}\n\ntry {\n    const endpoint = is_production ? 'https:\u002F\u002Fproduction-api.postmen.com\u002Fv3' : 'https:\u002F\u002Fsandbox-api.postmen.com\u002Fv3'\n    const response = await fetch(endpoint + '\u002Frates', {\n        method: 'POST',\n        body: JSON.stringify(payload),\n        headers: {\n            \"postmen-api-key\": api_key,\n            \"Content-Type\": \"application\u002Fjson\"\n        }\n    });\n    const data = await response.json();\n\n    if (data.meta.code != 200) {\n        console.log(data.meta)\n    }\n\n    for (let r = 0; r \u003C data.data.rates.length; r++) {\n        const rate = data.data.rates[r];\n\n        if (rate.service_name) {\n            rates.add(10000+r, rate.total_charge.amount, '', rate.service_name);\n        } else if (rate.error_message) {\n            console.log(rate.error_message);\n        }\n    }\n} catch(err) {\n  console.log(err);\n}\n\nfunction country_to_3(country) {\n    const iso3166_3 = {\n        AF: 'AFG', AX: 'ALA', AL: 'ALB', DZ: 'DZA', AS: 'ASM', AD: 'AND', AO: 'AGO', AI: 'AIA', AQ: 'ATA', AG: 'ATG', AR: 'ARG', AM: 'ARM', AW: 'ABW', AU: 'AUS', AT: 'AUT', AZ: 'AZE', BS: 'BHS', BH: 'BHR', BD: 'BGD', BB: 'BRB', BY: 'BLR', BE: 'BEL', BZ: 'BLZ', BJ: 'BEN', BM: 'BMU', BT: 'BTN', BO: 'BOL', BA: 'BIH', BW: 'BWA', BV: 'BVT', BR: 'BRA', VG: 'VGB', IO: 'IOT', BN: 'BRN', BG: 'BGR', BF: 'BFA', BI: 'BDI', KH: 'KHM', CM: 'CMR', CA: 'CAN', CV: 'CPV', KY: 'CYM', CF: 'CAF', TD: 'TCD', CL: 'CHL', CN: 'CHN', HK: 'HKG', MO: 'MAC', CX: 'CXR', CC: 'CCK', CO: 'COL', KM: 'COM', CG: 'COG', CD: 'COD', CK: 'COK', CR: 'CRI', CI: 'CIV', HR: 'HRV', CU: 'CUB', CY: 'CYP', CZ: 'CZE', DK: 'DNK', DJ: 'DJI', DM: 'DMA', DO: 'DOM', EC: 'ECU', EG: 'EGY', SV: 'SLV', GQ: 'GNQ', ER: 'ERI', EE: 'EST', ET: 'ETH', FK: 'FLK', FO: 'FRO', FJ: 'FJI', FI: 'FIN', FR: 'FRA', GF: 'GUF', PF: 'PYF', TF: 'ATF', GA: 'GAB', GM: 'GMB', GE: 'GEO', DE: 'DEU', GH: 'GHA', GI: 'GIB', GR: 'GRC', GL: 'GRL', GD: 'GRD', GP: 'GLP', GU: 'GUM', GT: 'GTM', GG: 'GGY', GN: 'GIN', GW: 'GNB', GY: 'GUY', HT: 'HTI', HM: 'HMD', VA: 'VAT', HN: 'HND', HU: 'HUN', IS: 'ISL', IN: 'IND', ID: 'IDN', IR: 'IRN', IQ: 'IRQ', IE: 'IRL', IM: 'IMN', IL: 'ISR', IT: 'ITA', JM: 'JAM', JP: 'JPN', JE: 'JEY', JO: 'JOR', KZ: 'KAZ', KE: 'KEN', KI: 'KIR', KP: 'PRK', KR: 'KOR', KW: 'KWT', KG: 'KGZ', LA: 'LAO', LV: 'LVA', LB: 'LBN', LS: 'LSO', LR: 'LBR', LY: 'LBY', LI: 'LIE', LT: 'LTU', LU: 'LUX', MK: 'MKD', MG: 'MDG', MW: 'MWI', MY: 'MYS', MV: 'MDV', ML: 'MLI', MT: 'MLT', MH: 'MHL', MQ: 'MTQ', MR: 'MRT', MU: 'MUS', YT: 'MYT', MX: 'MEX', FM: 'FSM', MD: 'MDA', MC: 'MCO', MN: 'MNG', ME: 'MNE', MS: 'MSR', MA: 'MAR', MZ: 'MOZ', MM: 'MMR', NA: 'NAM', NR: 'NRU', NP: 'NPL', NL: 'NLD', AN: 'ANT', NC: 'NCL', NZ: 'NZL', NI: 'NIC', NE: 'NER', NG: 'NGA', NU: 'NIU', NF: 'NFK', MP: 'MNP', NO: 'NOR', OM: 'OMN', PK: 'PAK', PW: 'PLW', PS: 'PSE', PA: 'PAN', PG: 'PNG', PY: 'PRY', PE: 'PER', PH: 'PHL', PN: 'PCN', PL: 'POL', PT: 'PRT', PR: 'PRI', QA: 'QAT', RE: 'REU', RO: 'ROU', RU: 'RUS', RW: 'RWA', BL: 'BLM', SH: 'SHN', KN: 'KNA', LC: 'LCA', MF: 'MAF', PM: 'SPM', VC: 'VCT', WS: 'WSM', SM: 'SMR', ST: 'STP', SA: 'SAU', SN: 'SEN', RS: 'SRB', SC: 'SYC', SL: 'SLE', SG: 'SGP', SK: 'SVK', SI: 'SVN', SB: 'SLB', SO: 'SOM', ZA: 'ZAF', GS: 'SGS', SS: 'SSD', ES: 'ESP', LK: 'LKA', SD: 'SDN', SR: 'SUR', SJ: 'SJM', SZ: 'SWZ', SE: 'SWE', CH: 'CHE', SY: 'SYR', TW: 'TWN', TJ: 'TJK', TZ: 'TZA', TH: 'THA', TL: 'TLS', TG: 'TGO', TK: 'TKL', TO: 'TON', TT: 'TTO', TN: 'TUN', TR: 'TUR', TM: 'TKM', TC: 'TCA', TV: 'TUV', UG: 'UGA', UA: 'UKR', AE: 'ARE', GB: 'GBR', US: 'USA', UM: 'UMI', UY: 'URY', UZ: 'UZB', VU: 'VUT', VE: 'VEN', VN: 'VNM', VI: 'VIR', WF: 'WLF', EH: 'ESH', YE: 'YEM', ZM: 'ZMB', ZW: 'ZWE', XK: 'XKX'\n    };\n\n    return iso3166_3[country];\n}",{"type":385,"attrs":2295,"content":2296},{"level":387,"textAlign":59},[2297],{"text":2116,"type":391},{"type":433,"attrs":2299,"content":2300},{"order":435},[2301,2308,2315,2322,2335,2353,2366,2373,2380],{"type":438,"content":2302},[2303],{"type":393,"attrs":2304,"content":2305},{"textAlign":59},[2306],{"text":2307,"type":391},"In the Foxy admin (admin.foxy.io), open the shipping settings for your store, scroll to Custom Shipping Code, and enable \"use custom code\".",{"type":438,"content":2309},[2310],{"type":393,"attrs":2311,"content":2312},{"textAlign":59},[2313],{"text":2314,"type":391},"In the code editor that appears, paste the code above. Do not save it yet.",{"type":438,"content":2316},[2317],{"type":393,"attrs":2318,"content":2319},{"textAlign":59},[2320],{"text":2321,"type":391},"In a new tab, log in to your Postmen account and go to the API keys section. Under Tokens, click \"Add new api key\" and complete the form.",{"type":438,"content":2323},[2324],{"type":393,"attrs":2325,"content":2326},{"textAlign":59},[2327,2329,2333],{"text":2328,"type":391},"Copy the generated API key from the Production or Testing tab (depending which type you created), then replace ",{"text":2330,"type":391,"marks":2331},"YOUR-POSTMEN-API-KEY",[2332],{"type":614},{"text":2334,"type":391}," in the code with it.",{"type":438,"content":2336},[2337],{"type":393,"attrs":2338,"content":2339},{"textAlign":59},[2340,2342,2346,2348,2352],{"text":2341,"type":391},"If you are using a Testing key, set ",{"text":2343,"type":391,"marks":2344},"is_production",[2345],{"type":614},{"text":2347,"type":391}," to ",{"text":2349,"type":391,"marks":2350},"false",[2351],{"type":614},{"text":416,"type":391},{"type":438,"content":2354},[2355],{"type":393,"attrs":2356,"content":2357},{"textAlign":59},[2358,2360,2364],{"text":2359,"type":391},"Update the ",{"text":2361,"type":391,"marks":2362},"shipper_accounts",[2363],{"type":614},{"text":2365,"type":391}," array to list every shipper account you want to request rates from. Shipper accounts are created in Postmen under Shipper Accounts. Make sure they match the environment (Production or Testing) of your key.",{"type":438,"content":2367},[2368],{"type":393,"attrs":2369,"content":2370},{"textAlign":59},[2371],{"text":2372,"type":391},"Configure the weight unit, length unit, and parcel dimensions to match your shipments.",{"type":438,"content":2374},[2375],{"type":393,"attrs":2376,"content":2377},{"textAlign":59},[2378],{"text":2379,"type":391},"Save your settings. Wait roughly 10 to 15 seconds, then refresh the page. If the save was successful, you will see your code again after refreshing.",{"type":438,"content":2381},[2382],{"type":393,"attrs":2383,"content":2384},{"textAlign":59},[2385],{"text":2386,"type":391},"Test it. Add a product from a live rate shippable category to your cart, then enter a shipping address on the cart or checkout. You should see rates returning from your Postmen account.",{"type":385,"attrs":2388,"content":2389},{"level":387,"textAlign":59},[2390],{"text":2165,"type":391},{"type":393,"attrs":2392,"content":2393},{"textAlign":59},[2394,2396,2400],{"text":2395,"type":391},"This is a basic setup. It returns every rate from Postmen and passes default values for the parcel. See the Postmen documentation on rate requests to customize the request further, and the ",{"text":592,"type":391,"marks":2397},[2398],{"type":401,"attrs":2399},{"href":2176,"uuid":583,"anchor":59,"target":405,"linktype":14},{"text":2401,"type":391}," to output only specific rates or work with them further.",{"type":393,"attrs":2403,"content":2404},{"textAlign":59},[2405,2407,2411],{"text":2406,"type":391},"Rates from custom shipping code are not currency converted by Foxy. For non USD stores, set the rate values in the cart's currency yourself. See ",{"text":2185,"type":391,"marks":2408},[2409],{"type":401,"attrs":2410},{"href":2189,"uuid":2190,"anchor":59,"target":405,"linktype":14},{"text":416,"type":391},{"id":59,"alt":59,"name":13,"focus":59,"title":59,"source":59,"filename":13,"copyright":59,"fieldtype":81,"meta_data":2413},{},"Connect your Postmen account to your Foxy store with the Custom Shipping Code feature to fetch live rates from Postmen's supported carriers at checkout.",[],"get-live-shipping-rates-with-postmen","help\u002Farticles\u002Fget-live-shipping-rates-with-postmen",-2040,[],"7ed94872-9644-491e-a811-478d04c51809",[],{"name":2423,"created_at":2424,"published_at":2425,"updated_at":2426,"id":2427,"uuid":2428,"content":2429,"slug":2580,"full_slug":2581,"sort_by_date":59,"position":2582,"tag_list":2583,"is_startpage":24,"parent_id":588,"meta_data":59,"group_id":2584,"first_published_at":2425,"release_id":59,"lang":65,"path":59,"alternates":2585,"default_full_slug":59,"translated_slugs":59},"Get Live Shipping Rates with Shippo","2026-06-08T17:48:25.276Z","2026-06-24T15:27:13.188Z","2026-06-24T15:27:13.211Z",185349346469428,"55aecd54-8815-45eb-a35e-667dbacf5546",{"_uid":2430,"body":2431,"name":2423,"image":2576,"pinned":24,"summary":2578,"category":320,"component":266,"related_articles":2579},"a82e30cf-65f2-4336-bd35-8a2ad8c5f2bc",{"type":382,"content":2432},[2433,2437,2442,2446,2450,2478,2482,2487,2492,2496,2551,2555,2566],{"type":385,"attrs":2434,"content":2435},{"level":387,"textAlign":59},[2436],{"text":390,"type":391},{"type":393,"attrs":2438,"content":2439},{"textAlign":59},[2440],{"text":2441,"type":391},"Shippo connects to more than 40 carriers through a single API. If you need rates from carriers that Foxy does not natively support (USPS, UPS, FedEx), you can fetch them from your Shippo account using Foxy's Custom Shipping Code feature. This article shows you the code to connect to Shippo and how to install it on your store.",{"type":385,"attrs":2443,"content":2444},{"level":387,"textAlign":59},[2445],{"text":2061,"type":391},{"type":393,"attrs":2447,"content":2448},{"textAlign":59},[2449],{"text":2066,"type":391},{"type":541,"content":2451},[2452,2459,2471],{"type":438,"content":2453},[2454],{"type":393,"attrs":2455,"content":2456},{"textAlign":59},[2457],{"text":2458,"type":391},"A Shippo account with a live API key (Shippo dashboard, under Settings > API).",{"type":438,"content":2460},[2461],{"type":393,"attrs":2462,"content":2463},{"textAlign":59},[2464,2465,2469],{"text":2252,"type":391},{"text":373,"type":391,"marks":2466},[2467],{"type":401,"attrs":2468},{"href":2257,"uuid":378,"anchor":59,"target":405,"linktype":14},{"text":2470,"type":391}," for how to turn it on.",{"type":438,"content":2472},[2473],{"type":393,"attrs":2474,"content":2475},{"textAlign":59},[2476],{"text":2477,"type":391},"At least one product category set to a delivery type of \"Shipped using live shipping rates\", so the custom code runs for it. See [Shipping and Categories].",{"type":385,"attrs":2479,"content":2480},{"level":387,"textAlign":59},[2481],{"text":2101,"type":391},{"type":393,"attrs":2483,"content":2484},{"textAlign":59},[2485],{"text":2486,"type":391},"This code reads the customer's shipment details from the cart payload, asks Shippo to create a shipment, then adds every rate Shippo returns to the cart.",{"type":653,"attrs":2488,"content":2489},{"class":59},[2490],{"text":2491,"type":391},"let myshippo = require('shippo')('YOUR_SHIPPO_LIVE_API_KEY');\n\nlet shipment = cart['_embedded']['fx:shipment'];\n\nlet addressFrom  = {\n    'state': shipment['origin_region'],\n    'zip': shipment['origin_postal_code'],\n    'country': shipment['origin_country']\n};\n\nlet addressTo = {\n    'name': shipment['first_name'] + \" \" + shipment['last_name'],\n    'company': shipment['company'],\n    'street1': shipment['address1'],\n    'city': shipment['city'],\n    'state': shipment['region'],\n    'zip': shipment['postal_code'],\n    'country': shipment['country'],\n    'is_residential': shipment['is_residential']\n};\n\nlet parcel = {\n    'length': '5',\n    'width': '5',\n    'height': '5',\n    'distance_unit': 'in',\n    'weight': shipment['total_weight'],\n    'mass_unit': 'lb',\n};\n\ntry {\n    let myshipment = await myshippo.shipment.create({\n        \"address_from\": addressFrom,\n        \"address_to\": addressTo,\n        \"parcels\": [parcel],\n        \"async\": false\n    });\n\n    let rate_options = await myshippo.shipment.rates(myshipment.object_id);\n\n    for (var i = 0; i \u003C rate_options.results.length; i++) {\n        rates.add((10000+i), rate_options.results[i]['amount'], rate_options.results[i]['provider'], rate_options.results[i]['servicelevel']['name']);\n    }\n} catch (e) {\n    console.log(e);\n    rates.error(\"Sorry, we're unable to get shipping rates at this time. Please try again, or contact us to finalize your order\");\n}",{"type":385,"attrs":2493,"content":2494},{"level":387,"textAlign":59},[2495],{"text":2116,"type":391},{"type":433,"attrs":2497,"content":2498},{"order":435},[2499,2505,2511,2518,2525,2537,2544],{"type":438,"content":2500},[2501],{"type":393,"attrs":2502,"content":2503},{"textAlign":59},[2504],{"text":2307,"type":391},{"type":438,"content":2506},[2507],{"type":393,"attrs":2508,"content":2509},{"textAlign":59},[2510],{"text":2314,"type":391},{"type":438,"content":2512},[2513],{"type":393,"attrs":2514,"content":2515},{"textAlign":59},[2516],{"text":2517,"type":391},"In a new tab, log in to your Shippo account and go to Settings, then API.",{"type":438,"content":2519},[2520],{"type":393,"attrs":2521,"content":2522},{"textAlign":59},[2523],{"text":2524,"type":391},"Under Tokens, click \"Generate Token\" beneath Live Tokens.",{"type":438,"content":2526},[2527],{"type":393,"attrs":2528,"content":2529},{"textAlign":59},[2530,2532,2536],{"text":2531,"type":391},"Copy the generated API key, then replace ",{"text":2533,"type":391,"marks":2534},"YOUR_SHIPPO_LIVE_API_KEY",[2535],{"type":614},{"text":2334,"type":391},{"type":438,"content":2538},[2539],{"type":393,"attrs":2540,"content":2541},{"textAlign":59},[2542],{"text":2543,"type":391},"Save your settings. The custom shipping code runs in a separate system, so wait roughly 15 to 20 seconds, then refresh the page. If the save was successful, you will see your code again after refreshing.",{"type":438,"content":2545},[2546],{"type":393,"attrs":2547,"content":2548},{"textAlign":59},[2549],{"text":2550,"type":391},"Test it. Add a product from a live rate shippable category to your cart, then enter a shipping address on the cart or checkout. You should see rates returning from your Shippo account.",{"type":385,"attrs":2552,"content":2553},{"level":387,"textAlign":59},[2554],{"text":2165,"type":391},{"type":393,"attrs":2556,"content":2557},{"textAlign":59},[2558,2560,2564],{"text":2559,"type":391},"This is a basic setup. It returns every rate from Shippo and uses default values for the parcel (a 5 by 5 by 5 inch box). Shippo provides optional extras in their API that you can use to extend the request. See the Shippo documentation on rate requests, and the ",{"text":592,"type":391,"marks":2561},[2562],{"type":401,"attrs":2563},{"href":2176,"uuid":583,"anchor":59,"target":405,"linktype":14},{"text":2565,"type":391}," to filter, rename, or reprice the returned rates.",{"type":393,"attrs":2567,"content":2568},{"textAlign":59},[2569,2571,2575],{"text":2570,"type":391},"Note that rates returned from custom shipping code are not currency converted by Foxy. If your store uses a currency other than USD, set or convert the rate values to the cart's currency yourself. See ",{"text":2185,"type":391,"marks":2572},[2573],{"type":401,"attrs":2574},{"href":2189,"uuid":2190,"anchor":59,"target":405,"linktype":14},{"text":416,"type":391},{"id":59,"alt":59,"name":13,"focus":59,"title":59,"source":59,"filename":13,"copyright":59,"fieldtype":81,"meta_data":2577},{},"Connect your Shippo account to your Foxy store with the Custom Shipping Code feature to fetch live rates from Shippo's supported carriers at checkout.",[404,583,378],"get-live-shipping-rates-with-shippo","help\u002Farticles\u002Fget-live-shipping-rates-with-shippo",-2020,[],"c154241f-a8ef-4338-8fbc-1a100cb354cf",[],{"name":2587,"created_at":2588,"published_at":2589,"updated_at":2590,"id":2591,"uuid":2592,"content":2593,"slug":2738,"full_slug":2739,"sort_by_date":59,"position":2740,"tag_list":2741,"is_startpage":24,"parent_id":588,"meta_data":59,"group_id":2742,"first_published_at":2589,"release_id":59,"lang":65,"path":59,"alternates":2743,"default_full_slug":59,"translated_slugs":59},"Passing Custom Fields to Shipping","2026-05-28T20:51:46.580Z","2026-05-28T21:09:21.751Z","2026-05-28T21:09:21.773Z",181501569401512,"ffe56d21-81f6-43e8-a1ac-2dde0f11125f",{"_uid":2594,"body":2595,"name":2587,"image":2732,"pinned":24,"summary":2734,"category":320,"component":266,"related_articles":2735},"3380abd4-b26b-4e4e-b56c-8bef98fe7973",{"type":382,"content":2596},[2597,2601,2606,2611,2628,2633,2638,2643,2653,2658,2668,2673,2678,2683,2705],{"type":385,"attrs":2598,"content":2599},{"level":387,"textAlign":59},[2600],{"text":390,"type":391},{"type":393,"attrs":2602,"content":2603},{"textAlign":59},[2604],{"text":2605,"type":391},"When using a Custom Shipping Endpoint or Custom Shipping Code, you may need to pass extra information beyond the standard cart data (such as whether a customer requested signature on delivery, or a preferred pickup location). Foxy provides three ways to include custom data in the shipping payload.",{"type":385,"attrs":2607,"content":2608},{"level":387,"textAlign":59},[2609],{"text":2610,"type":391},"Session attributes (h: prefix)",{"type":393,"attrs":2612,"content":2613},{"textAlign":59},[2614,2616,2620,2622,2626],{"text":2615,"type":391},"Any attribute added to the cart session with the ",{"text":2617,"type":391,"marks":2618},"h:",[2619],{"type":614},{"text":2621,"type":391}," prefix is automatically included in the shipping payload under the ",{"text":2623,"type":391,"marks":2624},"fx:custom_fields",[2625],{"type":614},{"text":2627,"type":391}," node. You add these as hidden inputs (or regular inputs) on your add to cart form:",{"type":653,"attrs":2629,"content":2630},{"class":59},[2631],{"text":2632,"type":391},"\u003Cinput type=\"hidden\" name=\"h:gift_wrap\" value=\"yes\">",{"type":393,"attrs":2634,"content":2635},{"textAlign":59},[2636],{"text":2637,"type":391},"These values persist in the session and are sent with every shipping rate request.",{"type":385,"attrs":2639,"content":2640},{"level":387,"textAlign":59},[2641],{"text":2642,"type":391},"Checkout fields (data-fc-shipping-custom-field)",{"type":393,"attrs":2644,"content":2645},{"textAlign":59},[2646,2648,2651],{"text":2647,"type":391},"For information you want to collect from the customer at checkout (not at add to cart time), add the ",{"text":1677,"type":391,"marks":2649},[2650],{"type":614},{"text":2652,"type":391}," data attribute to your checkout form elements. This works with checkboxes, radio buttons, text inputs, and select dropdowns.",{"type":653,"attrs":2654,"content":2655},{"class":59},[2656],{"text":2657,"type":391},"\u003Cinput type=\"checkbox\" id=\"sign_on_delivery\" name=\"sign_on_delivery\"\n  value=\"Yes\" {% if sign_on_delivery == \"Yes\" %}checked{% endif %}\n  data-fc-shipping-custom-field>\n\u003Clabel for=\"sign_on_delivery\">Signature on Delivery?\u003C\u002Flabel>",{"type":393,"attrs":2659,"content":2660},{"textAlign":59},[2661,2663,2666],{"text":2662,"type":391},"Whenever a field with this attribute changes, Foxy automatically re requests shipping rates with the updated values included in the payload. If a checkout field shares the same name as an existing ",{"text":2617,"type":391,"marks":2664},[2665],{"type":614},{"text":2667,"type":391}," session attribute, the checkout field's value overwrites the session value for the shipping request.",{"type":385,"attrs":2669,"content":2670},{"level":387,"textAlign":59},[2671],{"text":2672,"type":391},"JavaScript events",{"type":393,"attrs":2674,"content":2675},{"textAlign":59},[2676],{"text":2677,"type":391},"You can also inject or override custom fields programmatically using Foxy's shipping events:",{"type":653,"attrs":2679,"content":2680},{"class":59},[2681],{"text":2682,"type":391},"FC.client.on(\"checkout-shipping-options-update\", function(params) {\n  params.custom_fields = { my_custom_attr: true };\n});",{"type":393,"attrs":2684,"content":2685},{"textAlign":59},[2686,2688,2692,2694,2698,2700,2703],{"text":2687,"type":391},"The two relevant events are ",{"text":2689,"type":391,"marks":2690},"cart-shipping-options-update",[2691],{"type":614},{"text":2693,"type":391}," (for the cart\u002Fsidecart) and ",{"text":2695,"type":391,"marks":2696},"checkout-shipping-options-update",[2697],{"type":614},{"text":2699,"type":391}," (for the checkout page). Values set through these events overwrite matching session attributes but are themselves overwritten by any matching ",{"text":1677,"type":391,"marks":2701},[2702],{"type":614},{"text":2704,"type":391}," checkout fields.",{"type":393,"attrs":2706,"content":2707},{"textAlign":59},[2708,2710,2714,2716,2720,2721,2725,2726,2730],{"text":2709,"type":391},"These same events can also be used to dynamically override the shipping origin address by setting ",{"text":2711,"type":391,"marks":2712},"params.store_address",[2713],{"type":614},{"text":2715,"type":391}," with ",{"text":2717,"type":391,"marks":2718},"country",[2719],{"type":614},{"text":1018,"type":391},{"text":2722,"type":391,"marks":2723},"region",[2724],{"type":614},{"text":1034,"type":391},{"text":2727,"type":391,"marks":2728},"postal_code",[2729],{"type":614},{"text":2731,"type":391}," properties. This is useful if you ship from multiple locations and want to select the origin based on cart contents.",{"id":59,"alt":59,"name":13,"focus":59,"title":59,"source":59,"filename":13,"copyright":59,"fieldtype":81,"meta_data":2733},{},"Send additional data to your custom shipping endpoint or custom shipping code.",[2736,404,2737],"16cb7908-cbc7-4901-af7a-16bcfae70597","81e3dc1e-5e62-42aa-adf4-7191259b3bb3","passing-custom-fields-to-shipping","help\u002Farticles\u002Fpassing-custom-fields-to-shipping",-1930,[],"b30606ba-e6ec-49c1-8936-57a940363b98",[],{"name":2745,"created_at":2746,"published_at":2747,"updated_at":2748,"id":2749,"uuid":47,"content":2750,"slug":48,"full_slug":48,"sort_by_date":59,"position":2928,"tag_list":2929,"is_startpage":24,"parent_id":59,"meta_data":59,"group_id":2930,"first_published_at":2931,"release_id":59,"lang":65,"path":59,"alternates":2932,"default_full_slug":59,"translated_slugs":59},"Contact","2022-09-23T19:56:58.957Z","2025-05-08T18:24:40.382Z","2025-05-08T18:24:40.392Z",3138,{"seo":2751,"_uid":2754,"title":2755,"action":2756,"fields":2757,"method":2904,"columns":2905,"subtitle":2919,"component":48,"button_text":2925,"submit_title":2926,"submit_subtitle":2927},{"_uid":2752,"title":2745,"plugin":2753,"description":13},"24ff7574-3bcc-48d2-85b5-e529dfea1cc4","meta-fields","8f54f1da-9d8f-49b2-89e7-840e886491cb","We're here to help.","https:\u002F\u002Fusebasin.com\u002Ff\u002F029f48d65402",[2758,2763,2767,2875,2878,2883,2898],{"_uid":2759,"name":2760,"type":391,"label":2761,"options":13,"required":33,"component":2762,"placeholder":13},"9a70b226-2036-4f90-a052-b3efa61c5896","name","Name","form___field",{"_uid":2764,"name":2765,"type":2765,"label":2766,"options":13,"required":33,"component":2762,"placeholder":13},"86ba35be-ff43-4a28-8633-14052a8f6622","email","Email Address",{"_uid":2768,"name":2769,"type":2770,"label":2771,"options":2772,"required":33,"component":2762,"conditions":2773,"placeholder":13},"3f827475-492c-4f97-aa1e-2386ac263b6c","topic","select","Topic","Presales, Support, Billing, Partnerships, Order Enquiry, Other",[2774,2829,2839,2846,2854,2862,2868],{"_uid":2775,"equals":2776,"fields":2777,"component":2828},"e21d97dd-e68e-4fa6-ba97-bc40f3041dde","Order Enquiry",[2778],{"_uid":2779,"body":2780,"type":2826,"title":13,"component":2827},"b64992bc-6d53-48b8-b7a0-d81e5a062e50",{"type":382,"content":2781},[2782],{"type":393,"content":2783},[2784,2786,2793,2795,2797,2798,2802,2804,2809,2817,2819,2824],{"text":2785,"type":391},"We are ",{"text":2787,"type":391,"marks":2788},"Foxy.io",[2789],{"type":401,"attrs":2790},{"href":2791,"uuid":59,"anchor":59,"custom":2792,"target":59,"linktype":31},"http:\u002F\u002FFoxy.io",{},{"text":2794,"type":391},", an ecommerce platform powering ecommerce for other merchants. We do not sell products, and are unable to assist with questions about order statuses or refunds for any merchants using our platform. Please contact the merchant you ordered from for assistance. If you’d like to report a store using Foxy for fraudulent practices, please select ‘other’ in the subject.",{"type":2796},"hard_break",{"type":2796},{"text":2799,"type":391,"marks":2800},"NOTE:",[2801],{"type":449},{"text":2803,"type":391}," We are ",{"text":2805,"type":391,"marks":2806},"not ",[2807],{"type":2808},"italic",{"text":2810,"type":391,"marks":2811},"Foxy.in",[2812,2816],{"type":401,"attrs":2813},{"href":2814,"uuid":59,"anchor":59,"custom":2815,"target":59,"linktype":31},"http:\u002F\u002FFoxy.in",{},{"type":2808},{"text":2818,"type":391},". We are not in any way affiliated with ",{"text":2810,"type":391,"marks":2820},[2821],{"type":401,"attrs":2822},{"href":2814,"uuid":59,"anchor":59,"custom":2823,"target":59,"linktype":31},{},{"text":2825,"type":391},", and cannot help in any way with your order from that website.","danger","global___alert","form___condition",{"_uid":2830,"equals":2831,"fields":2832,"component":2828},"8765c3e1-25cf-44aa-b8ea-fc6094acf9c3","Presales",[2833],{"_uid":2834,"name":2835,"type":2836,"label":13,"options":13,"required":24,"component":2762,"conditions":2837,"placeholder":13,"default_value":2838},"cf464f8e-d643-4f6e-af29-d3abffaf7380","department_email_address","hidden",[],"hello@foxy.io",{"_uid":2840,"equals":208,"fields":2841,"component":2828},"4007b6d8-77e5-421d-bd1e-6f336dd853fb",[2842],{"_uid":2843,"name":2835,"type":2836,"label":13,"options":13,"required":24,"component":2762,"conditions":2844,"placeholder":13,"default_value":2845},"7b4c6aa5-a68c-45e0-9ce1-0a36af10c0c2",[],"help@foxy.io",{"_uid":2847,"equals":2848,"fields":2849,"component":2828},"1dbb8f11-613d-43cd-9e09-1b94f6e19219","Billing",[2850],{"_uid":2851,"name":2835,"type":2836,"label":13,"options":13,"required":24,"component":2762,"conditions":2852,"placeholder":13,"default_value":2853},"a0ac0d1b-bc4f-4a6c-a682-581d450b0b73",[],"help+billing@foxy.io",{"_uid":2855,"equals":2856,"fields":2857,"component":2828},"a0a53a50-7172-4a29-ba58-181e38874e12","Partnerships",[2858],{"_uid":2859,"name":2835,"type":2836,"label":13,"options":13,"required":24,"component":2762,"conditions":2860,"placeholder":13,"default_value":2861},"7aa011d9-f374-4aed-b5a5-929b54aaf152",[],"partners@foxy.io",{"_uid":2863,"equals":2776,"fields":2864,"component":2828},"a4cd431f-25d5-41c7-bfdc-02c908c8fb47",[2865],{"_uid":2866,"name":2835,"type":2836,"label":13,"options":13,"required":24,"component":2762,"conditions":2867,"placeholder":13,"default_value":2838},"f5d52168-d6ae-451b-94ee-2ced1cbd28ad",[],{"_uid":2869,"equals":2870,"fields":2871,"component":2828},"25aba1ed-eb41-4bbc-aa89-f7a7167ea86e","Other",[2872],{"_uid":2873,"name":2835,"type":2836,"label":13,"options":13,"required":24,"component":2762,"conditions":2874,"placeholder":13,"default_value":2838},"f40dfaef-c203-4b71-bf4e-e1b43cef192b",[],{"_uid":2876,"component":2877},"e9c53a05-f40a-4510-aaf8-bc072a235a0c","form___subject",{"_uid":2879,"name":2880,"type":2881,"label":2882,"options":13,"required":33,"component":2762,"placeholder":13},"a4c4d385-fff4-4978-99fb-b68cfea623d6","message","textarea","Message",{"_uid":2884,"name":2885,"type":2770,"label":2886,"options":2887,"required":33,"component":2762,"conditions":2888,"placeholder":13},"8a3c9f85-f438-427d-9c7a-d7b295a14b5b","existing_user","Are you an existing user?","No, Yes",[2889],{"_uid":2890,"equals":2891,"fields":2892,"component":2828},"115933d6-262a-4b59-8fa8-579c5ad73de1","Yes",[2893],{"_uid":2894,"name":2895,"type":391,"label":2896,"options":13,"required":33,"component":2762,"conditions":2897,"placeholder":13},"44b6ff23-98f0-4e95-b7f5-c23e06415c2d","subdomain","Store Subdomain",[],{"_uid":2899,"name":2900,"type":2770,"label":2901,"options":2902,"required":33,"component":2762,"conditions":2903,"placeholder":13},"922a5cef-3af2-4113-8855-36c7910e3ee3","user_type","What type of user are you?","Developer, Designer, Merchant",[],"POST",[2906],{"_uid":2907,"text":2908,"title":2917,"component":2918},"7323b90d-a93a-4bf1-baa9-20d0b7ead61b",{"type":382,"content":2909},[2910],{"type":393,"content":2911},[2912,2914,2915],{"text":2913,"type":391},"855.369.9227",{"type":2796},{"text":2916,"type":391},"9:30am-6pm Central M-F","Pre-sales, Sales, & Partnerships","contact___footer_column",{"type":382,"content":2920},[2921],{"type":393,"content":2922},[2923],{"text":2924,"type":391},"Get in touch to get help from our friendly support team.","Submit","Success!","Your email has been received. We'll get back to you as soon as we can, but it might take a business day. If you don't hear back from us in a timely manner, please check your spam folder to ensure our reply didn't go there.",-80,[],"2fd9fb7d-a48a-4184-acfd-30022d8d6f08","2022-09-23T20:10:45.360Z",[],{},1784562236248]