Ordering Personalized Products
When the user is done designing his project and hits the button to add it to the cart, we hand the information about this project over to your app through the transferCartProject
callback in the EditorViewDelegate
delegate.
extension MyViewController: EditorViewDelegate {
func transferCartProject(cartProject: CartProject) {
// Add the project to you cart here…
}
// other callbacks…
}
Cart Projects
A CartProject
represents a photo product after the user has finished editing and applying personalizations to it. It contains all necessary information to display it in your cart.
public struct CartProject {
let id: String
let revisionId: String
let editToken: String
let requiresAuthentication: Bool
let productName: String
let options: [String : String]
let price: Double
let expirationDate: Date
let title: String?
var previewImage: UIImage?
}
Re-Editing Cart Projects
To allow your users to further edit a project, which they have already put into the cart, you can just pass the cart project to the initializeEditor
method. This will return a View / ViewController for the editor with the cart project so you can just show it the same way like you did for creating new projects:
let editorViewController = IplabsMobileSdk.shared.initializeEditor(cartProject: yourCartProject)
editorViewController.editorViewDelegate = self
editorViewController.authenticationDelegate = AuthenticationService.shared
editorViewController.modalPresentationStyle = .fullScreen
self.present(editorViewController, animated: true)
Once the user is done editing his cart project, the transferCartProject
callback (see above) must called again with another instance of CartProject
. This instance has the same id
as the original one, but a different revisionId
, thus reflecting that it is a newer version of the same item.
Do not create a new item in your cart when receiving a CartProject
with an already existing id
, but update or replace the existing item with the data from the newer CartProject
instead. Also make sure to always use the correct revisionId
when ordering an item (see below), so the users don’t get an old version of their creation as a printed photo product.
Error Handling When Re-editing Cart Projects
The project for editing will not be fetched immediately from our backend. It is instead retrieved as soon as the editor view was loaded (in the viewDidLoad
lifecycle method). Because of this, we do not throw errors directly in the initializeEditor
method, but trigger the editCartProjectFailed
callback, which you have to implement in the EditorViewDelegate
. In case of an error during an attempt to edit a cart project, the ip.labs Mobile SDK will invoke editCartProjectFailed
with an error describing the cause of the problem.
extension MainViewController: EditorViewDelegate {
func editCartProjectFailed(reason: CartProjectEditingError) {
switch reason {
case .authenticationMissingError:
// you can handle errors explicitly
default:
// add a default case for errors you don’t want to handle explicitly
// (e.g. show a generic error message)
}
print(reason)
}
// other callbacks…
}
Creating an Order Item
After the user has passed your checkout process and the order shall be submitted, you need to create an OrderItem
which references the revisionId
of the cart project. Several revisions of a cart project can exist, so there is the need to differentiate between id
and revisionId
.
In the OrderItem
you can also set the quantity of the item and override the price (e.g. when discounts were applied).
let orderItem = OrderItem(
cartProjectRevisionId: cartProject.revisionId,
quantity: 2,
netPriceOverride: 9.99
)
Please make sure you use the revisionId
of the cart project when creating the OrderItem
, not the id
. Otherwise submitting an order will fail.
User Data for the Order
When submitting an order, our systems need some user data e.g. for shipping and billing the order. This information can be shared in two ways. If you are using our WipeSSO solution for syncing user sessions between your backend and ours, you just need to provide the session ID when invoking the method to submit the order. Our backend system will then fetch the user data from your WipeSSO endpoint and process the order accordingly.
The other way is to explicitly pass all relevant user information to our SDK with the UserInfo
type. Use this approach if you don’t plan to integrate our WipeSSO solution.
let postalAddress = Address(
countryIsoCode: "DE",
salutation: "Mr.",
firstName: "John",
lastName: "Doe",
street: "Main Street 123",
zipCode: "12345",
city: "Largetown",
phoneNumber: "0049123456789"
)
let userInfo = UserInfo(
eMailAddress: "j.doe@example.com",
billingAddress: postalAddress,
shippingAddress: postalAddress,
firstName: "John",
lastName: "Doe"
)
Submitting the Order
In addition to some OrderItems
and either UserInfo
or a session ID, we need a few more things to submit the order. The first is the order ID which should be generated from your systems, so you can also use them in your systems. The last thing is a secret to secure the order, so we know that this order request comes actually from your app and the payment is complete.
The secret will be generated by ip.labs and provided to you during the onboarding phase.
let result = await IplabsMobileSdk.shared.submitOrder(
id: "1234567",
items: orderItems,
secret: "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
userInfo: userInfo
)
switch result {
case .success(let orderId):
// communicate success to the user
case .failure(let orderError):
// give proper error message to user
}
When using WIPE SSO, just use the overload with the session ID instead of UserInfo
:
let result = await IplabsMobileSdk.shared.submitOrder(
id: "1234567",
items: orderItems,
secret: "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
sessionId: "xxxxxxxx")
)
switch result {
case .success(let orderId):
// communicate success to the user
case .failure(let orderError):
// give proper error message to user
}