# Apple Pay Hosted Checkout Initial Setup

## Initial Setup

**Contents**

* [Prerequisites](#prerequisites)
* [Client-Side Integration](#client-side-integration)
  * [Adding Reference to iFields](#adding-reference-to-ifields)
  * [Adding JavaScript Objects for Apple Pay button](#adding-javascript-objects-for-apple-pay-button)
  * [Enabling Apple Pay](#enable-apple-pay)
* [Server-Side Integration](#server-side-integration)
  * [Server Endpoint Creation](#server-endpoint-creation)
  * [API Integration](#api-integration)

## Prerequisites

**Set up Apple Pay Merchant ID**

Sola supports two solutions to help you set up your Apple Pay Merchant ID:

1. [Set up Apple Pay Merchant ID through your Merchant Portal](https://docs.solapayments.com/mobile-wallets/apple-pay-hosted-checkout/set-up-apple-pay-merchant-id-with-sola) - A simple solution where Sola handles all communications with Apple and takes care of all certificates.
2. [Set up Apple Pay Merchant ID using your own Apple account](https://docs.solapayments.com/mobile-wallets/apple-pay-hosted-checkout/apple-pay) - in this case it will be your responsibility for mainlining account, domain and certificates up to date with Apple.

## Implementing Apple Pay Hosted Checkout

### Client-Side Integration

#### Adding Reference to iFields

{% hint style="info" %}
Find the latest version of iFields at: [https://cdn.cardknox.com/ifields/versions.htm](https://nam10.safelinks.protection.outlook.com/?url=https%3A%2F%2Fcdn.cardknox.com%2Fifields%2Fversions.htm\&data=04%7C01%7Csaltman%40cardknox.com%7Cee27e2f8cee34d8eb64108d96965fb39%7Cbee12808a32d4518bad72e695a86fc91%7C0%7C0%7C637656709056206810%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000\&sdata=EkulORguWhCwZ%2BApGRr3WBqvzxcnnMsHj6w2nxzCwog%3D\&reserved=0)
{% endhint %}

&#x20;

**Step 1:** Add the iFields.js file after the \<head> tag on your payment page:

```html
<script src=https://cdn.cardknox.com/ifields/**ifields-version-number**/ifields.min.js></script>
```

&#x20;

#### Adding JavaScript Objects for Apple Pay button

**Step 1:** Add the following JS snippet inside the *\<body>* where the Apple Pay button is desired.

```html
<div id="ap-container">
</div>
```

&#x20;

**Step 2:** Create JavaScript object that holds all of the properties/methods required to process Apple Pay.

```javascript
window.apRequest = {
    buttonOptions: {
        buttonContainer: "ap-container",
        buttonColor: APButtonColor.black,
        buttonType: APButtonType.pay
    },
    ..............
    initAP: function() {
        return {
            buttonOptions: this.buttonOptions,
            merchantIdentifier: "<Your Apple Merchant Identifier provided by Cardknox>",
            requiredBillingContactFields: ['postalAddress', 'name', 'phone', 'email'],
            requiredShippingContactFields: ['postalAddress', 'name', 'phone', 'email'],
            onGetTransactionInfo: "apRequest.onGetTransactionInfo",
            onValidateMerchant: "apRequest.onValidateMerchant",
            onPaymentAuthorize: "apRequest.onPaymentAuthorize",
            onPaymentComplete: "apRequest.onPaymentComplete",
            onAPButtonLoaded: "apRequest.apButtonLoaded",
            isDebug: true
        };
    }
}
```

&#x20;                                       &#x20;

{% hint style="info" %}
For a full sample code please refer to [Apple Pay iFields Integration](https://docs.solapayments.com/mobile-wallets/apple-pay-hosted-checkout/apple-pay-ifields-integration)
{% endhint %}

&#x20;

**Step 3:** Implement desired callbacks.

For the list of available callbacks, please refer to [Apple Pay Object](https://docs.solapayments.com/mobile-wallets/apple-pay-hosted-checkout/apple-pay-hosted-checkout-objects-reference-request).

* There are three main callbacks that must be implemented (the rest are optional):
  * onGetTransactionInfo - calculates the total amount based on the charge amount, fees, taxes, shipping costs, etc.
  * onValidateMerchant - a callback to be called to validate the Apple Pay Merchant.
  * onPaymentAuthorize - a callback that will be called after the consumer pays and Apple returns a token with all of the requested consumer information, like the billing address, shipping address, etc. This is where you need to make an ajax call to your server with the Apple Payload. The sample for making an ajax call is below.

*Sample Code for Making Ajax Call:*

```javascript
validateApplePayMerchant: function (url) {
    return new Promise(function (resolve, reject) {
        try {
            var xhr = new XMLHttpRequest();
            xhr.open('POST', "https://api.cardknox.com/applepay/validate");
            xhr.onload = function () {
                if (this.status >= 200 && this.status < 300) {
                    resolve(xhr.response);
                } else {
                    reject({
                        status: this.status,
                        statusText: xhr.response
                    });
                }
            };
            xhr.onerror = function () {
                reject({
                    status: this.status,
                    statusText: xhr.statusText
                });
            };
            xhr.setRequestHeader("Content-Type", "application/json");
            xhr.send(JSON.stringify({ validationUrl: url}));
        } catch (err) {
            setTimeout(function () { alert("getApplePaySession error: " + exMsg(err)) }, 100);
        }
    });
},
authorize: function(applePayload, totalAmount) {
    return new Promise(function (resolve, reject) {
        var xhr = new XMLHttpRequest();
        xhr.open("POST", "https://<your domain>/<path to handle authorization>");
        xhr.onload = function () {
            if (this.status >= 200 && this.status < 300) {
                resolve(xhr.response);
            } else {
                reject({
                    status: this.status,
                    statusText: xhr.statusText
                });
            }
        };
        xhr.onerror = function () {
            reject({
                status: this.status,
                statusText: xhr.statusText
            });
        };
        const data = {
            amount: totalAmount,
            payload: applePayload
        };
        xhr.setRequestHeader("Content-Type", "application/json");
        xhr.send(JSON.stringify(data));
    });
}
```

{% hint style="info" %}
For full sample code, please refer to [Apple Pay iFields Integration](https://docs.solapayments.com/mobile-wallets/apple-pay-hosted-checkout/apple-pay-ifields-integration)
{% endhint %}

**Step 4:** Create JavaScript function that will initialize iFields.

```javascript
initAP: function() {
    return {
        buttonOptions: this.buttonOptions,
        merchantIdentifier: "merchant.cardknoxdev.com",
        requiredBillingContactFields: ['postalAddress', 'name', 'phone', 'email'],
        requiredShippingContactFields: ['postalAddress', 'name', 'phone', 'email'],
        onGetTransactionInfo: "apRequest.onGetTransactionInfo",
        onGetShippingMethods: "apRequest.onGetShippingMethods",
        onShippingContactSelected: "apRequest.onShippingContactSelected",
        onShippingMethodSelected: "apRequest.onShippingMethodSelected",
        onPaymentMethodSelected: "apRequest.onPaymentMethodSelected",
        onValidateMerchant: "apRequest.onValidateMerchant",
        onPaymentAuthorize: "apRequest.onPaymentAuthorize",
        onPaymentComplete: "apRequest.onPaymentComplete",
        onAPButtonLoaded: "apRequest.apButtonLoaded",
        isDebug: true
    };
}
```

initAP function above returns [Request Object](https://docs.solapayments.com/mobile-wallets/apple-pay-hosted-checkout/apple-pay-hosted-checkout-objects-reference-request).

#### Enable Apple Pay

**window\.ckApplePay object** - controls initialization of Apple Pay button

| **Method**     | **Call Required** | **Description**                                                                                                                   |
| -------------- | ----------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| enableApplePay | Yes               | <p>Initializes and enables Apple Pay Button.<br>Takes <a href="#enableapplepayparams-object">EnableApplePayParams</a> object.</p> |
| updateAmount   | Conditional       | Updates amount on Apple Sheet.                                                                                                    |

{% hint style="info" %}
You can provide either All, One, or None of the parameters for enableApplePay call.

* initFunction **Required** - either function name or function itself to initialize Apple Pay.
* amountField **Optional** - if specified, the Apple Pay total amount will be automatically updated whenever the amount has changed.
* amountField *is not* specified - in this case, it’s up to you to provide the correct amount for Apple Pay. One of the ways to do it is to call window\.ckApplePay.updateAmount manually.
  {% endhint %}

#### EnableApplePayParams Object

| **Name**     | **Type**       | **Required** | **Description**                                                                                                   |
| ------------ | -------------- | ------------ | ----------------------------------------------------------------------------------------------------------------- |
| initFunction | String\|Object | Yes          | Either function name or function itself to initialize Apple Pay                                                   |
| amountField  | String\|Object | No           | <p>Field containing amount.<br>Could be either the name of the field (String) or<br>the field itself (Object)</p> |

{% code title="Enable Apple Pay example" %}

```javascript
ckApplePay.enableApplePay({
  initFunction: 'apRequest.initAP',
  amountField: 'amount'
});
```

{% endcode %}

***

### Server-Side Integration

#### Server Endpoint Creation

A server endpoint is needed in order to accept the Apple Payload from Hosted Checkout.

**Step 1:** Create an endpoint and method for API Integration on your server side that takes an object containing total transaction amount and [Apple Payload](https://docs.solapayments.com/mobile-wallets/apple-pay-hosted-checkout-objects-reference-response#applepayload-object) and makes a call to Sola.\
Sample Object:

```
const req = {
    amount: 1.45,
    payload: <Payload from Apple Response>
}
```

#### API Integration

{% hint style="info" %}
This section assumes that you already know how to integrate other payments with [Cardknox API](https://docs.cardknox.com/api/transaction)
{% endhint %}

**Below are the steps to integrate Apple Pay with the Sola API:**

Once the consumer confirms the payment, Apple Pay API generates an [Apple Payload](https://docs.solapayments.com/mobile-wallets/apple-pay-hosted-checkout-objects-reference-response#applepayload-object) in the form of a JSON string.

Integration Steps:

1. Extract the paymentData from the payload.
2. Encode it with Base64 encoding.
3. Set `xCardNum` field to the encoded value above.
4. Set `xDigitalWalletType` to ApplePay.
5. Set the remaining required fields:
   1. `xAmount` the Transaction Amount.
   2. `xCommand` - Set to one of the values that starts with cc: like cc:sale, cc:auth, etc.
   3. `xBillFirstName`
   4. `xBillLastName`
   5. `xBillStreet`
   6. `xBillCity`
   7. `xBillState`
   8. `xBillZip`

Sample Request:

```javascript
public async Task<IActionResult> Authorize(AuthorizeRequest req) 
{
	var reqGateway = new
	{
		xKey = "Your xKey", 
		xAmount = (decimal)req.amount,
		xCommand = "cc:sale",
		xVersion = "4.5.4",
		xSoftwareName= "Your Software Name",
		xSoftwareVersion = "Your Software Version",
		xBillFirstName = req.paymentResponse.billingContact.givenName,
		xBillLastName = req.paymentResponse.billingContact.familyName,
		xBillStreet = req.paymentResponse.billingContact.addressLines[0],
		xBillCity = req.paymentResponse.billingContact.locality,
		xBillState = req.paymentResponse.billingContact.administrativeArea,
		xBillZip = req.paymentResponse.billingContact.postalCode,
		xShipFirstName = req.paymentResponse.shippingContact.givenName,
		xShipLastName = req.paymentResponse.shippingContact.familyName,
		xShipStreet = req.paymentResponse.shippingContact.addressLines[0],
		xShipCity = req.paymentResponse.shippingContact.locality,
		xShipState = req.paymentResponse.shippingContact.administrativeArea,
		xShipZip = req.paymentResponse.shippingContact.postalCode,
		xdigitalwallettype = "applepay",
		xcardnum = Convert.ToBase64String(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(req.payload.token.paymentData)))
	};
	var respMsg = "";
	using (var http = new HttpClient())
	{
		var resp = await http.PostAsJsonAsync("https://x1.cardknox.com/gatewayJSON", reqGateway);
		respMsg = await resp.Content.ReadAsStringAsync();
		.....
	}
	.....
}	
```

For more details, please contact your Sola Representative.

## Questions?

Contact <support@solapayments.com>
