Both sides previous revisionPrevious revisionNext revision | Previous revision |
v:2.0:using_foxy_without_the_cart [2017/05/29 02:47] – foxybrett | v:2.0:using_foxy_without_the_cart [2018/02/13 07:15] (current) – [Taxes] adam |
---|
A normal Foxy integration would look like this: | A normal Foxy integration would look like this: |
| |
- Your website has "add to cart" or "buy now" (or "donate now", etc.) buttons (links or forms). These buttons are ''a'' or ''form'' pointing to the ''/cart'' endpoint of your FoxyCart account. | - Your website has "add to cart" or "buy now" (or "donate now", etc.) buttons (links or forms). These buttons are ''a'' or ''form'' elements pointing to the ''/cart'' endpoint of your FoxyCart account. |
- A customer clicks one of those buttons. The browser submits a ''GET'' or ''POST'' request to the Foxy ''/cart'' endpoint. The cart is then displayed. By default, this would be the "sidecart" that slides in from the right, but it could also direct the customer to a new webpage showing only the cart, or it could take the customer directly to the checkout (which displays the cart in the right column). | - A customer clicks one of those buttons. The browser submits a ''GET'' or ''POST'' request to the Foxy ''/cart'' endpoint. The cart is then displayed. By default, this would be the "sidecart" that slides in from the right, but it could also direct the customer to a new webpage showing only the cart, or it could take the customer directly to the checkout (which displays the cart in the right column). |
- The customer lands on the Foxy-hosted checkout page. The customer completes the page and clicks to submit their payment. | - The customer lands on the Foxy-hosted checkout page. The customer completes the page and clicks to submit their payment. |
Let's imagine that you've already got your own cart functionality, however, and your "add to cart" buttons are already pointing to your own system. You want to continue using that functionality, but to have Foxy take over at the checkout portion. Here's how your integration would differ from the approach above: | Let's imagine that you've already got your own cart functionality, however, and your "add to cart" buttons are already pointing to your own system. You want to continue using that functionality, but to have Foxy take over at the checkout portion. Here's how your integration would differ from the approach above: |
| |
- Your website's "add to cart" buttons point to your ownsystem, and not to your store's ''/cart'' endpoint. | - Your website's "add to cart" buttons point to your own system, and not to your store's ''/cart'' endpoint. |
- Any cart that is displayed (prior to the checkout) is entirely handled by your system. | - Any cart that is displayed (prior to the checkout) is entirely handled by your system. |
- When the customer indicates they'd like to pay, your system… | - When the customer indicates they'd like to pay, your system… |
curl https://YOURDOMAIN.foxycart.com/cart\?name\=Cool%20Example\&price\=10\&color\=red\&code\=sku123\&output\=json | curl https://YOURDOMAIN.foxycart.com/cart\?name\=Cool%20Example\&price\=10\&color\=red\&code\=sku123\&output\=json |
</code> | </code> |
| |
| (Alternately, you could do a ''POST'' to your ''/cart'' endpoint, which may be easier if you're doing serverside interactions.) |
| |
You'll see JSON like this: | You'll see JSON like this: |
=== The Hypermedia API === | === The Hypermedia API === |
| |
If you're building a deeper integration, you may already be working with our [[https://api.foxycart.com/|Hypermedia REST API]]. For the purposes of this page, we'll assume basic working knowledge of the hAPI (including authentication via OAuth 2.0 and how to navigate using the hypermedia link relationships). This hAPI approach provides considerably more functionality, | <WRAP important> |
| //**__Experimental Functionality__**// |
| Though creating a cart via the hypermedia API is supported (and being used in production by some of our users), please drop us a note if you proceed with this approach, and if you encounter anything unexpected. Retrieving and setting shipping rates, in particular, isn't currently supported by the hypermedia API, so you'll need to use non-hAPI approaches (described below) in certain situations. |
| </WRAP> |
| |
| If you're building a deeper integration, you may already be working with our [[https://api.foxycart.com/|Hypermedia REST API]]. For the purposes of this page, we'll assume basic working knowledge of the hAPI (including authentication via OAuth 2.0 and how to navigate using the hypermedia link relationships). This hAPI approach provides considerably more functionality, as well as a consistent interface for all things related to your Foxy account, and can replicate the above ''/cart'' endpoint approach, albeit with a few more steps. |
| |
| The basic idea is to ''POST'' to the ''/carts'' resource URI (obtained from the hypermedia relations) for your store. <wrap tip>Note that you can ''PUT'' an entire cart</wrap> by taking the approach outlined in the "Modifiable Embedded Resources" section of [[https://api.foxycart.com/rels/carts|the ''carts'' resource documentation]]. Note that with this approach, you //will not// receive an ''fcsid'' session ID. In order to create a session associated with a cart, you'll need to use the [[https://api.foxycart.com/rels/create_session|''create_session'' link relation]] from the cart you've created. That will get you the ''fcsid'' value you'll use later. |
| |
| Regardless of the approach you take, you'll end up with a cart (ie. a collection of items). Once it's as it should be, the next step is getting the customer to pay for it. |
| |
| |
| |
=== Session Handling === | === Session Handling === |
| |
| The next step is to send the customer to the checkout to pay for the cart you've created. This is straightforward. Simply send the user (via a ''Location'' header or your preferred method) to ''https://YOURDOMAIN.foxycart.com/cart?cart=checkout&fcsid=YOUR_FCSID_VALUE_HERE''. |
| |
=== Single Sign-On (Incoming) === | === Single Sign-On (Incoming) === |
| |
| In situations where your customer is already authenticated in your system, you'll want to use our [[.:sso|Single Sign-On functionality]], so the user doesn't need to login again. If SSO is enabled for the store, a valid SSO auth token is required to load up the ''/checkout'' page. In the above ''cart=checkout'' example, the customer would then be redirected to your configured SSO endpoint URI. Your endpoint would then check the user's authentication (since your endpoint would generally be on the domain the user's logged in, so your endpoint could determine their logged-in status based on their cookies), and would generate the appropriate token and redirect the user back to a URL like this: |
| <code> |
| /checkout?fc_auth_token=AUTH_TOKEN&fcsid=SESSION_ID&fc_customer_id=CUSTOMER_ID×tamp=TIMESTAMP |
| </code> |
| |
| These multiple redirections aren’t necessary in a "mostly serverside" situation, however. If you already know the user is authenticated and want to send them directly to the checkout, you can send them to the ''/checkout'' URI with the ''fc_auth_token'' right in it. |
| |
| (Note that before sending a user, you'd need to create that user in Foxy. This would be done with the hAPI, and could be done either on-demand right before the redirection to ''/checkout'' takes place, or ahead of time (batched, triggered by user creation or updates, etc.).) |
| |
| |
| |
| |
=== Default Behavior === | === Default Behavior === |
| |
| By default, a successful checkout will land the user on a Foxy-hosted [[.:receipt|''/receipt'' page]], and will also trigger a [[.:transaction_xml_datafeed|webhook]] (which we often call a "datafeed"; way back when we named it, the term "webhook" wasn't the norm :). Though this receipt can be customized, for more advanced integrations like we're discussing here, it may not be sufficient. |
| |
=== Redirecting from the Receipt === | === Redirecting from the Receipt === |
| |
| If you'd like to redirect the customer to your own receipt, or perhaps to redirect them to another section of your site, you can easily do some conditional logic on the receipt to redirect the customer. There are a few possibilities here: |
| |
| * Empty the Foxy receipt template so it will //never// display anything, and will //always// redirect customers elsewhere. |
| * Use the Foxy receipt for historical purposes (as it's linked to by default in the email receipt templates), but set logic to immediately redirect on the initial view. |
| * Use the Foxy receipt without an immediate redirect, and allow an optional "Click here to continue…" to allow customers to continue to the next step. |
| * Other ideas? Feel free to contact us if you'd like to explore another option. |
| |
| Let's assume the 2nd bullet there, so a customer who's just purchased something will be immediately redirected to another page. You'd add some code to your template config [[.:receipt#display_conditional_content|as outlined here]], using the ''first_receipt_display'' boolean check if you want to ensure the redirection //only// happens on the very first viewing of the receipt. |
| |
| |
=== Single Sign-On (Outgoing) and User Synching === | === Single Sign-On (Outgoing) and User Synching === |
| |
| The final optional piece of the puzzle is outgoing SSO, so a customer (either brand new or returning) who's completed a transaction will be logged into your own system after their transaction. (This can be particularly useful for situations where customers are paying for access to content on your website, as they can go from the Foxy-powered checkout straight to the relevant section of your site, without needing to login again.) |
| |
| There are some examples of code on [[.:sso#outgoing_ssologging_a_customer_into_your_own_site_from_foxycart|the receipt documentation]], and if you're doing incoming SSO, it will be very familiar to you at this point. |
| |
| Note that though we don't support SAML by default, we can implement SAML for our Enterprise users. (Because of the complexities of synching users, it's not something that works "off the shelf", but it is doable either by us, or by you using an intermediary script to go from SAML to our own SSO approach.) |
| |
| |
| |
| ===== Shipping, Taxes, Coupons, and Other Considerations ===== |
| For this section, we'll be using the ''/cart'' endpoint, not the hypermedia API. (This functionality will be added to the hAPI, but is currently unavailable there.) |
| |
| ==== Taxes ==== |
| Taxes are applied automatically during the checkout process, but if you'd like to retrieve a tax estimate during your own checkout flow, you'd do the following: |
| |
| - Create the cart and session as outlined above. |
| - Attach a postal code to the session. Do this via the browser and review the javascript requests and responses made for your particular account, but it'll look something like this: ''https://EXAMPLE.foxycart.com/v/2.0.0/api_json.php?city=San+Diego®ion=CA&postal_code=92106&country=US&ThisAction=SaveCartContactInfo&fcsid=XXX&store_id=XXX'' (where you'd replace the ''XXX'' and domain as appropriate). |
| * There's also a ''GetAddressByPostalCode'' action that will retrieve possible cities based on an entered postal code, if you'd like to use that like the Foxy checkout, to do a bit of address validation. (This can help ensure more accurate tax rates.) |
| - Retrieve the tax information with a request to ''https://EXAMPLE.foxycart.com/cart?fcsid=XXX&output=json''. Display it however you'd like. |
| - **Note:** You may need to repeat the previous step after setting the shipping details for the transaction, as the tax value may change based on the shipping cost. |
| |
| ==== Shipping ==== |
| Shipping is also handled on the checkout automatically, but there may be situations where you'd like to set the shipping details (method name and price) without user input. There are a few possibilities here. |
| |
| === Step 1: Adding the rate to the session === |
| |
| The basic idea involves a request like this: |
| |
| <code> |
| https://EXAMPLE.foxycart.com/v/2.0.0/api_json.php?shipping_address_name=YYY&shipping_service_id=XXX&shipping_service_description=UPS+Ground&total_shipping=16.65&total_future_shipping=0&ThisAction=SaveShippingServiceInfo&fcsid=XXX&store_id=XXX |
| </code> |
| |
| (Note that the ''YYY'' value is used for [[.:multiship|multiship addresses]], and will normally be left empty if you're not using multiple shipping addresses in a single transaction.) |
| |
| **Using Foxy's Built-In Shipping Functionality:** |
| If you complete the steps above to get a tax, you'll notice the cart's JSON now contains a ''shipping_results'' node. You can use those values to submit back to the cart, passing through the values like the link above. Note that you can still use the [[.:shipping#custom_shipping_endpoint|custom shipping endpoint]] with this approach. |
| |
| **Using Arbitrary Shipping Amounts:** |
| You can also pass through arbitrary shipping details, which may be preferable in certain situations. A few caveats: |
| |
| * The ''shipping_service_id'' should be an integer greater than 10000. |
| * Signing requests: We are currently working to allow this approach to work with the "shipping rate signing" functionality enabled. Contact us for details. |
| |
| If you're going to use the Hypermedia API to push through the transaction programmatically at this point, you're done. If you're going to pass the customer on to the ''/checkout'' page to complete the transaction themselves, continue to Step 2. |
| |
| === Step 2: Handling the shipping on the checkout === |
| |
| This section will seem like extra work, and in many ways it is, but it ensures the integrity of the checkout. Even though you've already set the shipping rate you want, you'll need to do this again using the [[.:shipping#custom_shipping_endpoint|custom shipping endpoint]] functionality. |
| |
| If your endpoint returns the same details as you set in Step 1 above, the checkout will load with that shipping rate already selected and ready to go. |
| |
| (Note: If you're using [[.:sso|SSO (Single Sign On)]] and the user is authenticated, the rate may not be selected. Please contact us to discuss options with you so your users can avoid needing to select the shipping rate.) |
| ==== Coupons ==== |
| If you handle your own coupons or discounts within your system, you'll want to ensure those get passed through to Foxy appropriately. At present, Foxy doesn't allow passing through arbitrary discount/coupon amounts like it does shipping (above), so this is a bit more involved. |
| |
| - Calculate the appropriate discount in your system. Let's assume it's $10. |
| - [[https://wiki.foxycart.com/v/2.0/shipping#custom_shipping_endpoint|Create a coupon code]] using the hAPI for that amount (with the appropriate other details like display name and such). |
| - Add that coupon to the existing cart with a request like ''/cart?coupon=XXX'', where ''XXX'' is the coupon code as configured. |
| |
| A few notes: |
| |
| * You can remove coupons if necessary with a link like ''/cart?cart=remove_coupon&coupon_code_id=XXX&fcsid=XXX''. The respective ''coupon_code_id'' is available within the ''coupons'' node of the cart JSON for each coupon currently applied to the cart. |
| * If you have discounting logic that fits with Foxy's functionality, we recommend piggybacking on that. For example, if you have quantity discounts, we'd recommend using Foxy's built-in logic rather than calculating a discount and creating a unique code per transaction. Similarly, if a coupon's discounting logic can be replicated in Foxy, you can create a single coupon and reuse it. |
| |
| ===== Putting It All Together ===== |
| |
| Please let us know if you have any questions about this approach. You can always reach out to [[http://www.foxycart.com/contact|our support email]]. For advanced integrations like this, however, we are only able to offer support to users on our API Premium or Single-Store Advanced plans. |
| |
| |