Close service jobs

Learn how to set fulfillment data and set a job as complete.

Learn how to set fulfillment data, such as:

  • Start and end date-times
  • Fulfillment resources
  • Fulfillment documents such as Proof Of Appointment (POA) files
  • Job status, such as completed or cancelled

To set a job as complete, use the following operations:

Before you set a job as complete, you must provide appointment fulfillment data, using setAppointmentFulfillmentData and createServiceDocumentUploadDestination. There are four types of fulfillment data:

  • Estimated Arrival Time: The range of time when the technician is expected to arrive at the fulfillment location.
  • Appointment Fulfillment Times: The actual fulfillment date-time start and end.
  • Appointment Fulfillment Resources: The actual resources that fulfilled an appointment.
  • Appointment Fulfillment Documents: Documents that:
    • Serve as evidence of service completion
    • Were used in the course of fulfillment
    • Record aspects of fulfillment
📘

Note

The Amazon business line and service sellers determine the minimum requirements for fulfillment data and documents to close a job. Service sellers should confer with their relevant Amazon business line partners to settle appropriate API usage before they integrate with the Services API.

Prerequisites

To complete this tutorial, you need:

  • Authorization from the seller for whom you are making calls. Refer to Authorizing Selling Partner Applications for more information.
  • A service job identifier assigned to the service provider. Only jobs assigned to the service provider can be accessed. Job status are verified as in NotServiced state.
  • A scheduled appointment identifier pre-configured in Amazon Systems for the service provider.
  • An active appointment.

Step 1. Set or update service appointment fulfillment data

The setAppointmentFulfillmentData operation updates multiple aspects of service job appointment fulfillment data that you must record before you set a job as complete.

Step 2. Upload a fulfillment document

The createServiceDocumentUploadDestination operation creates a storage destination and identifier for a fulfillment document. This document is necessary to set a job as complete.

To upload a document:

  1. Create an upload destination for the service document with the createServiceDocumentUploadDestination operation.
  2. Encrypt and upload the file.

Use the information the response provides to encrypt and upload the file.

The following Java sample encrypts and uploads a feed. This sample code uses the Apache HTTP client.

  1. Use the following as input for the sample code:
    a. Your file content as the argument for the stream parameter of the InputStream method of the UploadToDestinationExample class.
    b. The initializationVector and key values from the createServiceDocumentUploadDestination response as arguments for the iv and key parameters of the EncryptionDetails method of the EncryptionDetails class.
    c. The url value from the createServiceDocumentUploadDestination response as the argument for the url parameter of the uploadToDestination method of the UploadToDestinationExample class.
  2. Save the sha256sum value to pass as the ContentSha256 parameter in setAppointmentFulfillmentData.
package com.amazon.spapi;

import org.apache.commons.io.IOUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.entity.InputStreamEntity;
import org.apache.http.impl.client.HttpClients;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.io.InputStream;
import java.security.DigestInputStream;
import java.security.GeneralSecurityException;
import java.security.Key;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Base64;

public class UploadToDestinationExample {
    static final String SHA_256 = "SHA-256";
    static final String AES = "AES";
    static final int AES_BLOCK_SIZE = 16;
    static final Base64.Encoder BASE64_ENCODER = Base64.getEncoder();
    static final Base64.Decoder BASE64_DECODER = Base64.getDecoder();
    static final CryptoProvider AES_CRYPTO_PROVIDER = UploadToDestinationExample::getInitializedCipher;

    static InputStream buildCipherInputStream(EncryptionDetails encryptionDetails, InputStream stream, int mode) {
        return new CipherInputStream(stream,
            AES_CRYPTO_PROVIDER.getInitializedCipher(mode, encryptionDetails));
    }

    private static InputStream buildCipherInputStream(EncryptionDetails encryptionDetails, InputStream stream) {
        return buildCipherInputStream(encryptionDetails, stream, Cipher.ENCRYPT_MODE);
    }

    static Cipher getInitializedCipher(int mode, EncryptionDetails details) {
        Cipher cipher;
        try {
            cipher = Cipher.getInstance(AES);
            Key key = new SecretKeySpec(BASE64_DECODER.decode(details.getKey()), AES);
            byte[] iv = BASE64_DECODER.decode(details.getIv());
            IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
            cipher.init(mode, key, ivParameterSpec, new SecureRandom());
        } catch (GeneralSecurityException e) {
            throw new IllegalStateException("Could not create Cipher for key-iv pair", e);
        }
        return cipher;
    }

    UploadDetails uploadToDestination(EncryptionDetails encryptionDetails, String uploadDestinationId, String url,
        String contentType,
        long documentLength,
        InputStream inputStream) {
        try {
            inputStream = buildCipherInputStream(encryptionDetails, inputStream);
            DigestInputStream sha256sumStream = new DigestInputStream(inputStream, MessageDigest.getInstance(SHA_256));
            inputStream = sha256sumStream;
            // Put the file
            HttpClient httpClient = HttpClients.createDefault();
            HttpPut httpPut = new HttpPut(url);
            // This content length calculation is specific to AES
            long contentLength = (documentLength / AES_BLOCK_SIZE + 1) *
                AES_BLOCK_SIZE;
            // This sets the Content-Length header since we specified the contentLength
            HttpEntity document = new InputStreamEntity(inputStream,
                contentLength);
            httpPut.setHeader("Content-Type", contentType);
            httpPut.setEntity(document);
            //Put the content in the S3 Pre-signed URL
            HttpResponse httpResponse = httpClient.execute(httpPut);
            if (httpResponse == null ||
                (httpResponse.getStatusLine().getStatusCode() / 100) != 2) {
                // Handle error responses here.
                throw new IllegalStateException("Could not upload to S3.");
            }
            // Document was successfully uploaded!
            byte[] sha256sumDigest = sha256sumStream.getMessageDigest().digest();
            String sha256sum = BASE64_ENCODER.encodeToString(sha256sumDigest);
            return new UploadDetails(uploadDestinationId, sha256sum);
        } catch (IOException | NoSuchAlgorithmException e) {
            throw new RuntimeException("Error occurred when attempting to encrypt or upload to S3.", e);
        } finally {
            IOUtils.closeQuietly(inputStream);
        }
    }
}

Step 3. Complete a service job

The completeServiceJobByServiceJobId operation marks a service job as complete. If the given job is the only active job in the order, then it marks the entire order as complete.

Step 4. Cancel a service job

The cancelServiceJobByServiceJobId operation marks a service job as cancelled. If the given job is the only active job in the order, then it marks the entire order as cancelled.

Cancellation reason codes by Amazon store

Reason codeReason descriptionDefaultHeavy bulk
S1Customer didn't show up.US, IN, UK, DEUS, IN, UK, DE
S2Customer outside service area.
DE
S3Work is different than scoped and order cannot be completed.US, IN, UK, DEUS, IN, UK, DE
S4Provider unable to contact customer.
DE
S5Provider cannot meet customer's schedule.
DE
S6Job requires professional trade license.
DE
S7 - S12Codes not in use.
S13Provider cannot meet original appointment.US, IN, UK, DEUS, IN, UK
S14Provider cannot meet new appointment request.USUS
S15Problem with Amazon product or its delivery.US, IN, UK, DEUS, IN, UK
S16Problem with non-Amazon product, delivery, or service.US, UK, DEUS, UK
S17I don't need this service.US, INUS, IN
S18 - S19Codes not in use.
S20Too expensive.ININ
S21 - S26Codes not in use.
S27Brand installed.ININ
S28Coverage area changed.
S29Pricing mistake.
S30No longer works with customer schedule.
S31Product damaged.IN
S32Risky site.IN
S33Customer wants cancellation.IN
S34Site not ready.IN
S35Product not delivered.IN
S36Additional material needed.IN
S37Customer wants reschedule.IN
S38Product returned.IN
S39We could not reach you.IN
S40Service already completed.IN
S41Service in another location.IN
S42Needs revisit.IN
S43Documents not available.IN
S44Slot missed.IN
S45Parts not available.IN
S46Wrong completion.IN
S47Need customer approval for repair.IN
S48 - S50Codes not in use.
S51Installation done by third party and customer does not require installation.IN
S52Product damaged, non-installable product, customer returned the product, or product gifted.IN
S53 - S54Codes not in use.
S55Restriction on visit.IN

Select a cancellation reason code

  1. Call the getServiceJobByServiceJobId operation and check for the marketplaceId value to identify the Amazon store details associated with the service order of a job.
  2. Call the getServiceJobByServiceJobId operation and check for the serviceType value to identify the service type of the job.
    • If serviceType is heavybulky, then search for a reason code in the Heavy Bulky column.
    • Otherwise, search for a reason code in the Default column.
  3. Select a reason code suitable for your use case and pass it as a query parameter when you request a job for cancellation.

Did this page help you?