{"metadata":{"image":[],"title":"","description":""},"api":{"url":"","auth":"required","results":{"codes":[]},"settings":"","params":[]},"next":{"description":"","pages":[]},"title":"Purchases and Abandoned Carts","type":"basic","slug":"purchases-and-abandoned-carts","excerpt":"How to send purchase and abandoned cart events through through the SDK.","body":"Purchases and abandoned carts sent to the Sailthru platform through the SDK. They can then be used for purchase attribution and to trigger abandoned cart flows in LO.\n\n### Purchase\nPurchases can be logged by creating a Purchase with an array containing all the PurchaseItems that are being purchased and providing it to the SDK.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"NSURL *itemUrl = [NSURL URLWithString::::at:::\\\"https://www.mobile.sailthru.com/not-a-real-item\\\"];\\n\\n// create purchase items\\nSTMPurchaseItem *item = [[STMPurchaseItem alloc] initWithQuantity:2 title:@\\\"Made Up Object\\\" price:1234 itemId:@\\\"2345\\\" itemUrl:itemUrl];\\n\\n// create purchase\\nSTMPurchase *purchase = [[STMPurchase alloc] initWithPurchaseItems:@[ item ]];\\n\\n// log purchase\\n[[SailthruMobile new] logPurchase:purchase withResponse:^(NSError * _Nullable error) {\\n  if (error) {\\n    // handle error\\n    return;\\n  }\\n  // handle success\\n}];\",\n      \"language\": \"objectivec\",\n      \"name\": \"iOS (Objective-C)\"\n    },\n    {\n      \"code\": \"let url = URL(string: \\\"https://www.mobile.sailthru.com/not-a-real-item\\\")\\n\\n// create purchase items\\nlet item = STMPurchaseItem(quantity: 2, title: \\\"Made Up Object\\\", price: 1234, itemId: \\\"2345\\\", itemUrl: url!)\\n\\n// create purchase\\nlet purchase = STMPurchase(purchaseItems: [ item ])\\n\\n// log purchase\\nSailthruMobile().logPurchase(purchase!) { (errorOrNil) in\\n\\t  if let error = errorOrNil {\\n        // handle error\\n        return\\n    }\\n    // handle success\\n}\",\n      \"language\": \"swift\",\n      \"name\": \"iOS (Swift)\"\n    },\n    {\n      \"code\": \"URI url = URI.create(\\\"https://www.mobile.sailthru.com/also-does-not-exist\\\");\\n\\n// create purchase items\\nPurchaseItem purchaseItem = new PurchaseItem(2, \\\"Made Up Object\\\", 1234, \\\"2345\\\", url);\\nArrayList<PurchaseItem> itemArrayList = new ArrayList<>();\\nitemArrayList.add(purchaseItem);\\n\\n// create purchase\\nPurchase purchase = new Purchase(itemArrayList);\\n\\n// log purchase\\nnew SailthruMobile().logPurchase(purchase, new SailthruMobile.SailthruMobileHandler<Void>() {\\n    @Override\\n    public void onSuccess(Void value) {\\n        // handle success\\n    }\\n\\n    @Override\\n    public void onFailure(Error error) {\\n        // handle error\\n    }\\n});\",\n      \"language\": \"java\",\n      \"name\": \"Android (Java)\"\n    },\n    {\n      \"code\": \"val url = URI.create(\\\"https://www.mobile.sailthru.com/also-does-not-exist\\\")\\n\\n// create purchase items\\nval purchaseItem = PurchaseItem(2, \\\"Made Up Object\\\", 1234, \\\"2345\\\", url)\\nval itemArrayList= listOf(purchaseItem) as ArrayList<PurchaseItem>\\n\\n// create purchase\\nval purchase = Purchase(itemArrayList)\\n\\n// log purchase\\nSailthruMobile().logPurchase(purchase, object : SailthruMobileHandler<Void?> {\\n    override fun onSuccess(value: Void?) {\\n        // handle success\\n    }\\n\\n    override fun onFailure(error: Error?) {\\n        // handle error\\n    }\\n})\",\n      \"language\": \"kotlin\",\n      \"name\": \"Android (Kotlin)\"\n    },\n    {\n      \"code\": \"// create purchases\\nvar purchaseItem1 = new SailthruMobile.PurchaseItem(1, \\\"title\\\", 1234, \\\"2345\\\", \\\"https://www.mobile.sailthru.com/not-a-real-item\\\");\\nvar purchaseItems = [ purchaseItem ];\\n\\n// create purchase\\nvar purchase = new SailthruMobile.Purchase(purchaseItems);\\n\\n// log purchase\\nSailthruMobile.logPurchase(purchase).then(result => {\\n  // handle success\\n}).catch(e => {\\n  // handle error\\n});\",\n      \"language\": \"javascript\",\n      \"name\": \"React Native (JavaScript)\"\n    }\n  ]\n}\n[/block]\n### Abandoned Cart\nAn abandoned cart requires the same purchase item details as a regular purchase, so the setup is very similar but with a different method call.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"NSURL *itemUrl = [NSURL URLWithString:@\\\"https://www.mobile.sailthru.com/not-a-real-item\\\"];\\n\\n// create purchase items\\nSTMPurchaseItem *item = [[STMPurchaseItem alloc] initWithQuantity:2 title:@\\\"Made Up Object\\\" price:1234 itemId:@\\\"2345\\\" itemUrl:itemUrl];\\n\\n// create purchase\\nSTMPurchase *purchase = [[STMPurchase alloc] initWithPurchaseItems:@[ item ]];\\n\\n// log abandoned cart\\n[[SailthruMobile new] logAbandonedCart:purchase withResponse:^(NSError * _Nullable error) {\\n  if (error) {\\n    // handle error\\n    return;\\n  }\\n  // handle success\\n}];\",\n      \"language\": \"objectivec\",\n      \"name\": \"iOS (Objective-C)\"\n    },\n    {\n      \"code\": \"let url = URL(string: \\\"https://www.mobile.sailthru.com/not-a-real-item\\\")\\n\\n// create purchase items\\nlet item = STMPurchaseItem(quantity: 2, title: \\\"Made Up Object\\\", price: 1234, itemId: \\\"2345\\\", itemUrl: url!)\\n\\n// create purchase\\nlet purchase = STMPurchase(purchaseItems: [ item ])\\n\\n// log abandoned cart\\nSailthruMobile().logAbandonedCart(purchase!) { (errorOrNil) in\\n\\t  if let error = errorOrNil {\\n        // handle error\\n        return\\n    }\\n    // handle success\\n}\",\n      \"language\": \"swift\",\n      \"name\": \"iOS (Swift)\"\n    },\n    {\n      \"code\": \"URI url = URI.create(\\\"https://www.mobile.sailthru.com/also-does-not-exist\\\");\\n\\n// create purchase items\\nPurchaseItem purchaseItem = new PurchaseItem(2, \\\"Made Up Object\\\", 1234, \\\"2345\\\", url);\\nArrayList<PurchaseItem> itemArrayList = new ArrayList<>();\\nitemArrayList.add(purchaseItem);\\n\\n// create purchase\\nPurchase purchase = new Purchase(itemArrayList);\\n\\n// log abandoned cart\\nnew SailthruMobile().logAbandonedCart(purchase, new SailthruMobile.SailthruMobileHandler<Void>() {\\n    @Override\\n    public void onSuccess(Void value) {\\n        // handle success\\n    }\\n\\n    @Override\\n    public void onFailure(Error error) {\\n        // handle error\\n    }\\n});\",\n      \"language\": \"java\",\n      \"name\": \"Android (Java)\"\n    },\n    {\n      \"code\": \"val url = URI.create(\\\"https://www.mobile.sailthru.com/also-does-not-exist\\\")\\n\\n// create purchase items\\nval purchaseItem = PurchaseItem(2, \\\"Made Up Object\\\", 1234, \\\"2345\\\", url)\\nval itemArrayList= listOf(purchaseItem) as ArrayList<PurchaseItem>\\n\\n// create purchase\\nval purchase = Purchase(itemArrayList)\\n\\n// log abandoned cart\\nSailthruMobile().logAbandonedCart(purchase, object : SailthruMobileHandler<Void?> {\\n    override fun onSuccess(value: Void?) {\\n      // handle success\\n    }\\n\\n    override fun onFailure(error: Error?) {\\n      // handle error\\n    }\\n})\",\n      \"language\": \"kotlin\",\n      \"name\": \"Android (Kotlin)\"\n    },\n    {\n      \"code\": \"// create purchases\\nvar purchaseItem1 = new SailthruMobile.PurchaseItem(1, \\\"title\\\", 1234, \\\"2345\\\", \\\"https://www.mobile.sailthru.com/not-a-real-item\\\");\\nvar purchaseItems = [ purchaseItem ];\\n\\n// create purchase\\nvar purchase = new SailthruMobile.Purchase(purchaseItems);\\n\\n// log abandoned cart\\nSailthruMobile.logAbandonedCart(purchase).then(result => {\\n  // handle success\\n}).catch(e => {\\n  // handle error\\n});\",\n      \"language\": \"javascript\",\n      \"name\": \"React Native (JavaScript)\"\n    }\n  ]\n}\n[/block]\n\n[block:callout]\n{\n  \"type\": \"info\",\n  \"title\": \"Note\",\n  \"body\": \"When using the `logAbandonedCart` SDK function, the SDK sets the channel automatically. If you're sending carts by other methods (for example, your servers) ensure that they only send web carts. Sending a mobile cart by another method will overwrite mobile carts sent by the SDK.\"\n}\n[/block]\n\n### Content Items\nPurchase Items can also be created from ContentItem instances that have been returned in the `getRecommendations` method.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"STMPurchaseItem *purchaseItem = [[STMPurchaseItem alloc] initWithContentItem:contentItem];\",\n      \"language\": \"objectivec\",\n      \"name\": \"iOS (Objective-C)\"\n    },\n    {\n      \"code\": \"let purchaseItem = STMPurchaseItem(contentItem: contentItem)\",\n      \"language\": \"swift\",\n      \"name\": \"iOS (Swift)\"\n    },\n    {\n      \"code\": \"PurchaseItem purchaseItem = new PurchaseItem(contentItem);\",\n      \"language\": \"java\",\n      \"name\": \"Android (Java)\"\n    },\n    {\n      \"code\": \"val purchaseItem = PurchaseItem(contentItem)\",\n      \"language\": \"kotlin\",\n      \"name\": \"Android (Kotlin)\"\n    },\n    {\n      \"code\": \"var purchaseItem = SailthruMobile.PurchaseItem.fromContentItem(contentItem);\",\n      \"language\": \"javascript\",\n      \"name\": \"React Native (JavaScript)\"\n    }\n  ]\n}\n[/block]\nAlternatively if you have an array of ContentItem instances you can create the purchase with them directly.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"STMPurchase *purchase = [[STMPurchase alloc] initWithContentItems:contentItems];\",\n      \"language\": \"objectivec\",\n      \"name\": \"iOS (Objective-C)\"\n    },\n    {\n      \"code\": \"let purchase = STMPurchase(contentItems: contentItems)\",\n      \"language\": \"swift\",\n      \"name\": \"iOS (Swift)\"\n    },\n    {\n      \"code\": \"Purchase purchase = new Purchase(contentItems);\",\n      \"language\": \"java\",\n      \"name\": \"Android (Java)\"\n    },\n    {\n      \"code\": \"val purchase = Purchase(contentItems)\",\n      \"language\": \"kotlin\",\n      \"name\": \"Android (Kotlin)\"\n    },\n    {\n      \"code\": \"var purchase = SailthruMobile.Purchase.fromContentItems(contentItems);\",\n      \"language\": \"javascript\",\n      \"name\": \"React Native (JavaScript)\"\n    }\n  ]\n}\n[/block]","updates":[],"order":12,"isReference":false,"hidden":false,"sync_unique":"","link_url":"","link_external":false,"_id":"5e6156bf5e4a51006dcd8187","project":"55e67aaa9cc7c62b00c4a1ea","version":{"version":"1.5","version_clean":"1.5.0","codename":"ST Rebrand","is_stable":true,"is_beta":false,"is_hidden":false,"is_deprecated":false,"categories":["5e6156bf5e4a51006dcd8120","5e6156bf5e4a51006dcd8121","5e6156bf5e4a51006dcd8122","5e6156bf5e4a51006dcd8123","5e6156bf5e4a51006dcd8124","561c61b4ad272c0d00a892df","586c014c0abf1d0f000d04d4","58991d2ad207df0f0002186b","5e6156bf5e4a51006dcd8125","5e6156bf5e4a51006dcd8126","5af0fe494ca2730003cbc98a","5af0fe55ec80af0003804ca2","5e69868cbd5dcb006b35867b","5e6986ca2c6652006791b6e8"],"_id":"5e6156bf5e4a51006dcd818c","project":"55e67aaa9cc7c62b00c4a1ea","__v":2,"forked_from":"5b720760c44b7600034b7a08","createdAt":"2015-09-02T04:27:23.612Z","releaseDate":"2015-09-02T04:27:23.612Z"},"category":{"sync":{"isSync":false,"url":""},"pages":[],"title":"Advanced Techniques","slug":"advanced-techniques","order":6,"from_sync":false,"reference":false,"_id":"5e6156bf5e4a51006dcd8125","project":"55e67aaa9cc7c62b00c4a1ea","createdAt":"2017-02-08T21:31:11.878Z","__v":0,"version":"5e6156bf5e4a51006dcd818c"},"user":"5b0b7a46a26e6400036604fd","createdAt":"2019-07-10T04:25:57.488Z","__v":0,"parentDoc":null}

Purchases and Abandoned Carts

How to send purchase and abandoned cart events through through the SDK.

Purchases and abandoned carts sent to the Sailthru platform through the SDK. They can then be used for purchase attribution and to trigger abandoned cart flows in LO. ### Purchase Purchases can be logged by creating a Purchase with an array containing all the PurchaseItems that are being purchased and providing it to the SDK. [block:code] { "codes": [ { "code": "NSURL *itemUrl = [NSURL URLWithString:@\"https://www.mobile.sailthru.com/not-a-real-item\"];\n\n// create purchase items\nSTMPurchaseItem *item = [[STMPurchaseItem alloc] initWithQuantity:2 title:@\"Made Up Object\" price:1234 itemId:@\"2345\" itemUrl:itemUrl];\n\n// create purchase\nSTMPurchase *purchase = [[STMPurchase alloc] initWithPurchaseItems:@[ item ]];\n\n// log purchase\n[[SailthruMobile new] logPurchase:purchase withResponse:^(NSError * _Nullable error) {\n if (error) {\n // handle error\n return;\n }\n // handle success\n}];", "language": "objectivec", "name": "iOS (Objective-C)" }, { "code": "let url = URL(string: \"https://www.mobile.sailthru.com/not-a-real-item\")\n\n// create purchase items\nlet item = STMPurchaseItem(quantity: 2, title: \"Made Up Object\", price: 1234, itemId: \"2345\", itemUrl: url!)\n\n// create purchase\nlet purchase = STMPurchase(purchaseItems: [ item ])\n\n// log purchase\nSailthruMobile().logPurchase(purchase!) { (errorOrNil) in\n\t if let error = errorOrNil {\n // handle error\n return\n }\n // handle success\n}", "language": "swift", "name": "iOS (Swift)" }, { "code": "URI url = URI.create(\"https://www.mobile.sailthru.com/also-does-not-exist\");\n\n// create purchase items\nPurchaseItem purchaseItem = new PurchaseItem(2, \"Made Up Object\", 1234, \"2345\", url);\nArrayList<PurchaseItem> itemArrayList = new ArrayList<>();\nitemArrayList.add(purchaseItem);\n\n// create purchase\nPurchase purchase = new Purchase(itemArrayList);\n\n// log purchase\nnew SailthruMobile().logPurchase(purchase, new SailthruMobile.SailthruMobileHandler<Void>() {\n @Override\n public void onSuccess(Void value) {\n // handle success\n }\n\n @Override\n public void onFailure(Error error) {\n // handle error\n }\n});", "language": "java", "name": "Android (Java)" }, { "code": "val url = URI.create(\"https://www.mobile.sailthru.com/also-does-not-exist\")\n\n// create purchase items\nval purchaseItem = PurchaseItem(2, \"Made Up Object\", 1234, \"2345\", url)\nval itemArrayList= listOf(purchaseItem) as ArrayList<PurchaseItem>\n\n// create purchase\nval purchase = Purchase(itemArrayList)\n\n// log purchase\nSailthruMobile().logPurchase(purchase, object : SailthruMobileHandler<Void?> {\n override fun onSuccess(value: Void?) {\n // handle success\n }\n\n override fun onFailure(error: Error?) {\n // handle error\n }\n})", "language": "kotlin", "name": "Android (Kotlin)" }, { "code": "// create purchases\nvar purchaseItem1 = new SailthruMobile.PurchaseItem(1, \"title\", 1234, \"2345\", \"https://www.mobile.sailthru.com/not-a-real-item\");\nvar purchaseItems = [ purchaseItem ];\n\n// create purchase\nvar purchase = new SailthruMobile.Purchase(purchaseItems);\n\n// log purchase\nSailthruMobile.logPurchase(purchase).then(result => {\n // handle success\n}).catch(e => {\n // handle error\n});", "language": "javascript", "name": "React Native (JavaScript)" } ] } [/block] ### Abandoned Cart An abandoned cart requires the same purchase item details as a regular purchase, so the setup is very similar but with a different method call. [block:code] { "codes": [ { "code": "NSURL *itemUrl = [NSURL URLWithString:@\"https://www.mobile.sailthru.com/not-a-real-item\"];\n\n// create purchase items\nSTMPurchaseItem *item = [[STMPurchaseItem alloc] initWithQuantity:2 title:@\"Made Up Object\" price:1234 itemId:@\"2345\" itemUrl:itemUrl];\n\n// create purchase\nSTMPurchase *purchase = [[STMPurchase alloc] initWithPurchaseItems:@[ item ]];\n\n// log abandoned cart\n[[SailthruMobile new] logAbandonedCart:purchase withResponse:^(NSError * _Nullable error) {\n if (error) {\n // handle error\n return;\n }\n // handle success\n}];", "language": "objectivec", "name": "iOS (Objective-C)" }, { "code": "let url = URL(string: \"https://www.mobile.sailthru.com/not-a-real-item\")\n\n// create purchase items\nlet item = STMPurchaseItem(quantity: 2, title: \"Made Up Object\", price: 1234, itemId: \"2345\", itemUrl: url!)\n\n// create purchase\nlet purchase = STMPurchase(purchaseItems: [ item ])\n\n// log abandoned cart\nSailthruMobile().logAbandonedCart(purchase!) { (errorOrNil) in\n\t if let error = errorOrNil {\n // handle error\n return\n }\n // handle success\n}", "language": "swift", "name": "iOS (Swift)" }, { "code": "URI url = URI.create(\"https://www.mobile.sailthru.com/also-does-not-exist\");\n\n// create purchase items\nPurchaseItem purchaseItem = new PurchaseItem(2, \"Made Up Object\", 1234, \"2345\", url);\nArrayList<PurchaseItem> itemArrayList = new ArrayList<>();\nitemArrayList.add(purchaseItem);\n\n// create purchase\nPurchase purchase = new Purchase(itemArrayList);\n\n// log abandoned cart\nnew SailthruMobile().logAbandonedCart(purchase, new SailthruMobile.SailthruMobileHandler<Void>() {\n @Override\n public void onSuccess(Void value) {\n // handle success\n }\n\n @Override\n public void onFailure(Error error) {\n // handle error\n }\n});", "language": "java", "name": "Android (Java)" }, { "code": "val url = URI.create(\"https://www.mobile.sailthru.com/also-does-not-exist\")\n\n// create purchase items\nval purchaseItem = PurchaseItem(2, \"Made Up Object\", 1234, \"2345\", url)\nval itemArrayList= listOf(purchaseItem) as ArrayList<PurchaseItem>\n\n// create purchase\nval purchase = Purchase(itemArrayList)\n\n// log abandoned cart\nSailthruMobile().logAbandonedCart(purchase, object : SailthruMobileHandler<Void?> {\n override fun onSuccess(value: Void?) {\n // handle success\n }\n\n override fun onFailure(error: Error?) {\n // handle error\n }\n})", "language": "kotlin", "name": "Android (Kotlin)" }, { "code": "// create purchases\nvar purchaseItem1 = new SailthruMobile.PurchaseItem(1, \"title\", 1234, \"2345\", \"https://www.mobile.sailthru.com/not-a-real-item\");\nvar purchaseItems = [ purchaseItem ];\n\n// create purchase\nvar purchase = new SailthruMobile.Purchase(purchaseItems);\n\n// log abandoned cart\nSailthruMobile.logAbandonedCart(purchase).then(result => {\n // handle success\n}).catch(e => {\n // handle error\n});", "language": "javascript", "name": "React Native (JavaScript)" } ] } [/block] [block:callout] { "type": "info", "title": "Note", "body": "When using the `logAbandonedCart` SDK function, the SDK sets the channel automatically. If you're sending carts by other methods (for example, your servers) ensure that they only send web carts. Sending a mobile cart by another method will overwrite mobile carts sent by the SDK." } [/block] ### Content Items Purchase Items can also be created from ContentItem instances that have been returned in the `getRecommendations` method. [block:code] { "codes": [ { "code": "STMPurchaseItem *purchaseItem = [[STMPurchaseItem alloc] initWithContentItem:contentItem];", "language": "objectivec", "name": "iOS (Objective-C)" }, { "code": "let purchaseItem = STMPurchaseItem(contentItem: contentItem)", "language": "swift", "name": "iOS (Swift)" }, { "code": "PurchaseItem purchaseItem = new PurchaseItem(contentItem);", "language": "java", "name": "Android (Java)" }, { "code": "val purchaseItem = PurchaseItem(contentItem)", "language": "kotlin", "name": "Android (Kotlin)" }, { "code": "var purchaseItem = SailthruMobile.PurchaseItem.fromContentItem(contentItem);", "language": "javascript", "name": "React Native (JavaScript)" } ] } [/block] Alternatively if you have an array of ContentItem instances you can create the purchase with them directly. [block:code] { "codes": [ { "code": "STMPurchase *purchase = [[STMPurchase alloc] initWithContentItems:contentItems];", "language": "objectivec", "name": "iOS (Objective-C)" }, { "code": "let purchase = STMPurchase(contentItems: contentItems)", "language": "swift", "name": "iOS (Swift)" }, { "code": "Purchase purchase = new Purchase(contentItems);", "language": "java", "name": "Android (Java)" }, { "code": "val purchase = Purchase(contentItems)", "language": "kotlin", "name": "Android (Kotlin)" }, { "code": "var purchase = SailthruMobile.Purchase.fromContentItems(contentItems);", "language": "javascript", "name": "React Native (JavaScript)" } ] } [/block]