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 from the EditorCallbacks
interface.
val callbacks = object : EditorCallbacks {
override fun 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.
data class CartProject(
val id: String,
val revisionId: String,
val editToken: String,
val requiresAuthentication: Boolean,
val productName: String,
val options: Map<String, String>,
val price: Double,
val expirationDate: Instant,
val title: String?,
val previewImage: Bitmap?
)
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:
editor.initialize(
cartProject = yourCartProject,
callbacks = yourEditorCallbacks
)
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. 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 EditorCallbacks
construct. 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.
val callbacks = object : EditorCallbacks {
override fun editCartProjectFailed(reason: CartProjectEditingError) {
// Handle errors here…
}
// 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).
val orderItem = OrderItem(
cartProjectRevisionId = cartProject.cartProjectRevisionId,
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.
val postalAddress = Address(
countryIsoCode = "DE",
salutation = "Mr.",
firstName = "John",
lastName = "Doe",
street = "Main Street 123",
zipCode = "12345",
city = "Largetown",
phoneNumber = "0049123456789"
)
val 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.
when (
IplabsMobileSdk.submitOrder(
id = "12345678",
items = yourOrderItems,
secret = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
userInfo = yourUserInfo
)
) {
OrderResult.Success -> {
// Handle successful order here (e.g. clear cart and show confirmation)…
}
is OrderResult.ConnectionError, is OrderResult.HttpError -> {
// Handle communication-related errors here (e.g. offer retry)…
}
OrderResult.DuplicateOrderIdError, OrderResult.InvalidSignatureError,
OrderResult.RevisionIdNotFoundError, is OrderResult.UnknownError -> {
// Handle potentially unrecoverable errors here (e.g. display error
// message and support contact info)…
}
}
When using WIPE SSO, just use the overload with the session ID instead of UserInfo
:
when (
IplabsMobileSdk.submitOrder(
id = "12345678",
items = yourOrderItems,
secret = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
sessionId = yourSessionId
)
) {
OrderResult.Success -> {
// Handle successful order here (e.g. clear cart and show confirmation)…
}
is OrderResult.ConnectionError, is OrderResult.HttpError -> {
// Handle communication-related errors here (e.g. offer retry)…
}
OrderResult.DuplicateOrderIdError, OrderResult.InvalidSignatureError,
OrderResult.RevisionIdNotFoundError, is OrderResult.UnknownError -> {
// Handle potentially unrecoverable errors here (e.g. display error
// message and support contact info)…
}
}