# Generate QR Code for Merchants
source: https://developer.mastercard.com/mastercard-checkout-solutions/documentation/use-cases/sqr/generate-qr-codes/sqr-generate-qr/index.md

## Overview {#overview}

Acquirers/PSPs are responsible for generating the QR codes for participating merchants. The QR code must follow the [EMVCo Merchant Presented QR specifications](https://www.emvco.com/emv-technologies/qrcodes/).

Below is an example of a Secure Card on File QR. Note that additional fields are supported as per the EMVCo Merchant Presented QR specifications.

    000201010211057704736a2f41a3-c54c-fce8-32d2-0324e1c32e22*3440e5bf-81ca-4c5f-a1b2-cf989f09a03952045024530384054031005802US5913Test Merchant6008New York62080304123463046F6D"

The digital wallet needs to scan the QR code and extract the QR fields. The table below provides a mapping of the QR fields with the fields in the SQR APIs.

|                    Field Name in EMVCo Specs                    |                                                                                                                                                                                                                                                                                                                                           Definition                                                                                                                                                                                                                                                                                                                                            | ID/Tag |        Format        |    Length     |  Presence   |                                   Value                                    |      Field name in SQR APIs       |
|-----------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------|----------------------|---------------|-------------|----------------------------------------------------------------------------|-----------------------------------|
| Payload Format Indicator                                        | Defines the version of the QR Code template and hence the conventions on the identifiers, lengths, and values. *Must be the first data object in the QR Code.*                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  | 00     | Numeric              | 02            | Mandatory   | 01                                                                         | `payloadFormatIndicator`          |
| Point of Initiation Method                                      | Identifies the communication technology (here QR Code) and whether the data is static or dynamic. The Point of Initiation Method has a value of "11" for static QR Codes and a value of "12" for dynamic QR Codes. *Use value of "11" for static QR code.*                                                                                                                                                                                                                                                                                                                                                                                                                                      | 01     | Numeric              | 02            | Optional    | 11                                                                         | `pointOfInitiationMethod`         |
| Merchant Account Information - MC SQR identifiers (sub-tag 04). | Network Specific Tag used to identify the merchant account and SQR specific requirements. "05" is reserved for Mastercard. *The 2 values are concatenated with a '\*'.*                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         | 05     | String               | var. up to 99 | Mandatory   | 6a2f41a3-c54c-fce8-32d2-0324e1c32e22\*3440e5bf-81ca-4c5f-a1b2-cf989f09a039 | `recipientIdCheckout`; `srcDpaId` |
| Merchant Category Code                                          | As defined by \[ISO 18245\] and assigned by the Acquirer                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | 52     | Numeric              | 04            | Mandatory   | 5024                                                                       |                                   |
| Transaction Currency                                            | Indicates the currency code of the transaction. A 3-digit numeric value, as defined by \[ISO 4217\]. This value will be used by the mobile application to display a recognizable currency to the consumer whenever an amount is being displayed or whenever the consumer is prompted to enter an amount.                                                                                                                                                                                                                                                                                                                                                                                        | 53     | Numeric              | 03            | Mandatory   | 840                                                                        | `transactionCurrencyCode`         |
| Transaction Amount                                              | The transaction amount, if known. For instance, "99.34". If present, this value is displayed to the consumer by the mobile application when processing the transaction. If this data object is not present, the consumer is prompted to input the transaction amount to be paid to the merchant. *Only required for dynamic QR codes; if not included the SRCI NP must pass it when initiating the checkout call.*                                                                                                                                                                                                                                                                              | 54     | Numeric              | var. up to 13 | Conditional | 100                                                                        | `transactionAmount`               |
| Country Code                                                    | Indicates the country of the merchant acceptance device. A 2-character alpha value, as defined by \[ISO 3166-1 alpha 2\] and assigned by the Acquirer. The country may be displayed to the consumer by the mobile application when processing the transaction.                                                                                                                                                                                                                                                                                                                                                                                                                                  | 58     | Alphanumeric Special | 02            | Mandatory   | US                                                                         | `countryCode`                     |
| Merchant Name                                                   | The "doing business as" name for the merchant, recognizable to the consumer. This name may be displayed to the consumer by the mobile application when processing the transaction. *Must be provided for the digital wallet to display within the wallet application.*                                                                                                                                                                                                                                                                                                                                                                                                                          | 59     | Alphanumeric Special | var. up to 25 | Mandatory   | Test Merchant                                                              | `merchantName`                    |
| Merchant City                                                   | City of operations for the merchant. This name may be displayed to the consumer by the mobile application when processing the transaction. *Must be provided for the digital wallet to display within the wallet application.*                                                                                                                                                                                                                                                                                                                                                                                                                                                                  | 60     | Alphanumeric Special | var. up to 15 | Mandatory   | New York                                                                   | `merchantCity`                    |
| Additional Data Field Template                                  | This includes the following: * Bill Number (ID 01) * Mobile Number (ID 02) * Store Label (ID 03) * Loyalty Number (ID 04) * Reference Label (ID 05) * Customer Label (ID 06) * Terminal Label (ID 07) * Purpose of transaction (ID 08) * Additional Consumer Data Request (ID 09) <br /> The Additional Data Field Template includes information that may be provided by the Merchant or may be populated by the mobile application to enable or facilitate certain use cases. Store ID is used to identify sub-merchant/ merchant store if provided by consumer, * acceptanceChannelData * consumerData If provided by merchant/ Acquirers/PSPs, <!-- --> * acceptanceChannelData * sellerData | 62     | String               | var. up to 99 | Optional    | 0304124                                                                    | `storeId`                         |
| Cyclic Redundancy Check (CRC)                                   | Checksum calculated over all the data objects included in the QR Code. *Must be the last data object in the QR Code.*                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           | 63     | Alphanumeric Special | 04            | 570E        | Test Merchant                                                              |                                   |

## Device SDKs {#device-sdks}

The following Software Development Kits (SDKs) can be used by the acquirer/PSP to generate the QR codes for the digital wallet to scan, parse and verify QR codes.

|      SDK      |                                                                                           Audience                                                                                            |
|---------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Java Core SDK | * The digital wallet to parse and verify QR code content for web applications and Android applications. * The acquirer/PSP to generate QR codes for web applications and Android applications |

The Java Core SDK can be used by:

* The digital wallet to parse and verify QR code content for web applications and Android applications
* The acquirer/PSP to generate QR codes for web applications and Android applications

### Downloaded Libraries: {#downloaded-libraries}

* [pushpayment-core-sdk-2.0.9.3-javadoc.jar](https://static.developer.mastercard.com/content/mastercard-checkout-solutions/uploads/pushpayment-core-sdk-2.0.9.3-javadoc.jar) (168KB)
* [pushpayment-core-sdk-2.0.9.3.jar](https://static.developer.mastercard.com/content/mastercard-checkout-solutions/uploads/pushpayment-core-sdk-2.0.9.3.jar) (74KB)

#### Adding Dependencies with Gradle: {#adding-dependencies-with-gradle}

Configure your build.gradle file to include the following:

**build.gradle**

```build.gradle
dependencies {
  implementation fileTree(dir: 'libs', include: ['*.jar'])
  implementation 'com.google.zxing:core:3.3.0' // This is a java library for generating Bitmap Image
}
```

### Usage {#usage}

#### Generate QR Code {#generate-qr-code}

This function can be used to generate a QR code

**Java**

```Java
public void generateQRCode(){
  // construct the PushPaymentData object
  PushPaymentData pushPaymentData = new PushPaymentData();

  try {
    // Set required properties on push payment data e.g pushPaymentData.payloadFormatIndicator = "01"

    // Payload format indicator
    pushPaymentData.setPayloadFormatIndicator("01");

    // Point of initiation method
    pushPaymentData.setValue("01", "12");

    // Merchant category code
    pushPaymentData.setMerchantCategoryCode("1434");

    // Transaction currency code
    pushPaymentData.setTransactionCurrencyCode("156");

    // Transaction amount - Optional Tag
    pushPaymentData.setValue("54","100.8");

    // Country code
    pushPaymentData.setCountryCode("CN");

    // Merchant name
    pushPaymentData.setMerchantName("BEST TRANSPORT");

    // Merchant city
    pushPaymentData.setMerchantCity("BEIJING");

    // Postal code - Optional Tag
    pushPaymentData.setPostalCode("56748");

    // Additional data - Optional Tag
    AdditionalData addData = new AdditionalData();
    addData.setStoreId("A6008");
    addData.setLoyaltyNumber("***");
    addData.setTerminalId("A6008667");
    addData.setAdditionalDataRequest("ME");
    pushPaymentData.setAdditionalData(addData);

    // Mastercard Data (Tag 05)- Optional Tag
    MastercardData masterCardData = new MastercardData();
    String recipientIdCheckout = "6a2f41a3-c54c-fce8-32d2-0324e1c32e22";
    String srcDpaId = "123456789123456789123456789123456789";
    // Method setSRCID() of MastercardData tag object will add Sub Tag 04 (SRC ID) value in form recipientIdCheckout*srcDpaId
    masterCardData.setSRCID(recipientIdCheckout,srcDpaId);
    pushPaymentData.setMastercardData(masterCardData);

  } catch (Exception e) {
    System.out.println("Error occurred during creation of pushpaymentdata: " + e.getMessage());
  }

  try {
    String qrContent = pushPaymentData.generatePushPaymentString();
    Bitmap map = encodeToQrCode(qrContent);
    System.out.println("QR content : " + qrContent);
  } catch (Exception e) {
    // do something for the exception
  }
}

private Bitmap encodeToQrCode(String text) {
  QRCodeWriter writer = new QRCodeWriter();
  BitMatrix matrix;
  int width = 200;  // get desired QR code width
  int height = 200; // get desired QR code height

  try {
    Map<EncodeHintType, Object> hintMap = new EnumMap<EncodeHintType, Object>(EncodeHintType.class);
    hintMap.put(EncodeHintType.CHARACTER_SET, "UTF-8");     // for allowing Chinese characters
    matrix = writer.encode(text, BarcodeFormat.QR_CODE, width, height, hintMap);

  } catch (WriterException ex) {
    ex.printStackTrace();
    return null;
  }

  Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
  for (int x = 0; x < width; x++) {
    for (int y = 0; y < height; y++) {
      bmp.setPixel(x, y, matrix.get(x, y) ? Color.BLACK : Color.WHITE);
    }
  }

  return bmp;
}
```

Additional Secure Card on File QR indicators must be included in the QR code within the Mastercard Data Tag (Tag 05). An identifier for the acquirer/PSP (**recipientIdCheckout** ) and a merchant identifier (**srcDpaId** ) must be present within the SRCID (Sub Tag 04) in the Mastercard Data Tag (Tag 05), delimited with an asterisk '**\***'.

### Get Mastercard Data {#get-mastercard-data}

This function can be used to retrieve the `MastercardData` (TAG_05_MASTERCARD_DATA) instance from a QR code string.

**Java**

```Java
/**
 * Returns MastercardData instance at TAG05.
 *
 * @return value of MastercardData stored if it exists, null if it does not.
 */
public MastercardData getMastercardData() {
  Serializable data = getValue(PPTag.TAG_05_MASTERCARD_DATA);
  return data == null ? null : (MastercardData) data;
}
```

### Get Merchant Category Code {#get-merchant-category-code}

This function can be used to retrieve the merchant category code (TAG_52) from a QR code string.

**Java**

```Java
/**
 * Returns merchant category code.
 *
 * @return value of merchant category code
 */
public String getMerchantCategoryCode() {
  return getStringValue(PPTag.TAG_52_MERCHANT_CATEGORY_CODE);
}
```

### Get AdditionalData Value {#get-additionaldata-value}

This function can be used to retrieve the additional data tag value (TAG_62) from a QR code string.

**Java**

```Java
private void getAdditionalDataValueFromQRString(String qrCode){
  try {
    String additionalData =  Parser.getAdditionalDataValueFromQRString(qrCode);
    System.out.println(additionalData);
  } catch (Exception e){
    System.out.println(e.getMessage());
  }
}
```

### Parse QR Code Content {#parse-qr-code-content}

This function can be used to parse QR code content. This function throws an exception when a QR code is not compliant with the EMVCo merchant presented QR specification.

**Java**

```Java
private void parseQRCode(String code) {
  PushPaymentData qrcode;
  try {
    qrcode = Parser.parse(code);
    System.out.println(qrcode.dumpData());
  } catch (ConflictiveTagException e) {
    System.out.println("ConflictiveTagException : " + e);
  } catch (InvalidTagValueException e) {
    System.out.println("InvalidTagValueException : " + e);
  } catch (MissingTagException e) {
    System.out.println("MissingTagException : " + e);
  } catch (UnknownTagException e) {
    System.out.println("UnknownTagException : " + e);
  } catch (FormatException e) {
    System.out.println("FormatException : " + e);
  }
}
```

#### Parse QR Code Content with Validation Warning {#parse-qr-code-content-with-validation-warning}

Unlike the parseQRCode function above, this function will not throw an exception for InvalidTagValue, RFU Tag and Missing Tag. Instead, it returns a PushPaymentData object with a validation error when the scanned QR code is not compliant with the EMVCo Merchant Presented QR specification.

**Java**

```Java
private void parseQRCodeWithWarnings(String code){
  try {
    PushPaymentData data = Parser.parseWithValidationWarnings(code);
    for (MPQRError error : data.validationErrors) {
      System.out.println("validation error : " + error.errorMessage);
      System.out.println("validation error tag : " + error.getErrorTag().getTag());
      System.out.println("validation error root tag : " + error.getErrorRootTag());
      System.out.println("validation error value : " + error.getErrorValue());
    }
  } catch (ConflictiveTagException e) {
    System.out.println("ConflictiveTagException : " + e);
  } catch (DuplicateTagException e) {
    System.out.println("InvalidTagValueException : " + e);
  } catch (UnknownTagException e) {
    System.out.println("UnknownTagException : " + e);
  } catch (FormatException e) {
    System.out.println("FormatException : " + e);
  }
}
```

## Android QR Scan SDK {#android-qr-scan-sdk}

The Android QR Scan SDK can be used by Originating Institutions and Wallet Providers to scan the QR code and parse and verify the content in the Android application. This SDK uses the Java Core SDK to parse and verify the QR code content.

### Download Libraries {#download-libraries}

[qr-scan-sdk-release-1.0.4.aar](https://static.developer.mastercard.com/content/mastercard-checkout-solutions/uploads/qr-scan-sdk-release-1.0.4.aar) (44KB)

### Features {#features}

* Can be used via Intents (little code required)
* Can be embedded in an Activity, for advanced customization of UI and logic
* Scanning can be performed in landscape or portrait mode
* The camera is managed in a background thread, for fast startup time
* Return constructed object for the correct Push Payment QR code

### Adding aar Dependency with Gradle {#adding-aar-dependency-with-gradle}

This library supports KitKat and later versions of Android (API level 19+).

1. Copy the qr-scan-sdk-release-1.0.4.aar located inside qr-scan-sdk-release-1.0.4.zip and pushpayment-core-sdk-2.0.9.3.jar into your project libs folder.
2. Configure your build.gradle file:

**build.gradle**

```build.gradle
repositories {
  flatDir {
    dirs 'libs'
  }
}

dependencies {
  implementation fileTree(dir: 'libs', include: ['*.jar'])
  implementation (name: 'qr-scan-sdk-release-1.0.4', ext: 'aar')
  implementation 'com.journeyapps:zxing-android-embedded:3.4.0'

  // Other dependencies  required by the android application
  // Note : Appcompat minimum version supported is v7:23.1.0
}

android {
  // Minimum version supported is 24.0.0. Older versions may give compile errors
  buildToolsVersion '29.0.3'
}
```

### Usage with IntentIntegrator {#usage-with-intentintegrator}

**Java**

```Java
new PPIntentIntegrator(this).initiateScan(); // `this` is the current Activity

// Get the results:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  if (resultCode == RESULT_OK) {
    PushPaymentData qrcode = (PushPaymentData) data.getSerializableExtra(PPIntents.PUSH_PAYMENT_DATA);
    if (qrcode != null) {
      try {
        String qrString = qrcode.generatePushPaymentString();
        Toast.makeText(this, qrString, Toast.LENGTH_LONG).show();
      } catch (Exception e) {
        // do something for the exception
      }
    }
  } else if (resultCode == RESULT_CANCELED) {
    if (data != null) {
      FormatException e = (FormatException) data.getSerializableExtra(PPIntents.PARSE_ERROR); // get the exception reason
      if (e != null) {
          Toast.makeText(this, "Exception: "+e.getMessage(), Toast.LENGTH_LONG).show();
      }
      // you can also check if the partial QR code is returned, then grab any data you want from it
      PushPaymentData qrcode = (PushPaymentData) data.getSerializableExtra(PPIntents.PUSH_PAYMENT_DATA);
    }
  }
  super.onActivityResult(requestCode, resultCode, data);
}
```

### Layout and Function Customization {#layout-and-function-customization}

**Java**

```Java
package com.mastercard.labs.sng.qrscantester;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;

import com.google.zxing.client.android.Intents;
import com.journeyapps.barcodescanner.DecoratedBarcodeView;
import com.mastercard.mpqr.pushpayment.scan.activity.PPCaptureActivity;


public class CustomizedCaptureActivity extends PPCaptureActivity {
  // you can define your own return code
  public static final int RESULT_OK_WITH_MERCHANT_ID = 15;
  public static final String MERCHANT_ID_INTENT = "MERCHANT_ID_INTENT";

  private EditText merchantIdEditText;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // add ref to your new element
    merchantIdEditText = (EditText) findViewById(R.id.edit_merchant_id);
  }

  @Override
  protected DecoratedBarcodeView initializeContent() {
    // specify the new customized layout
    this.setContentView(R.layout.activity_pp_capture_customized);
    return (DecoratedBarcodeView)this.findViewById(com.mastercard.mpqr.pushpayment.scan.R.id.zxing_barcode_scanner);
  }

  // you can bind your new event
  public void onOKPressed(View view) {
    String merchantId = merchantIdEditText.getText().toString();
    Intent intent = new Intent(Intents.Scan.ACTION);
    intent.putExtra(MERCHANT_ID_INTENT, merchantId);
    this.setResult(RESULT_OK_WITH_MERCHANT_ID, intent);
    finish();
  }

  @Override
  public void toggleTorch(View view) {
    super.toggleTorch(view);
  }

  @Override
  public void goBack(View view) {
    super.goBack(view);
  }
}
```

## iOS Core SDK {#ios-core-sdk}

The iOS Core SDK can be used by:

* The digital wallet to parse and verify QR code content for web applications and Android applications
* The acquirer/PSP to generate QR codes for web applications and Android applications

This SDK only provides the core functionality to parse and generate the content of the QR code. If you need a UI component to scan the QR code, you can use the iOS QR Scan SDK.

This SDK is developed in Objective-C and it works with Swift.

### Installation {#installation}

#### Swift {#swift}

1. Download the latest release of MPQR Scan SDK. [MPQRCoreSDK.xcframework.zip](https://static.developer.mastercard.com/content/mastercard-checkout-solutions/uploads/MPQRCoreSDK.xcframework.zip) (1MB)
2. Unzip the file and place it in the project folder.
3. Go to Xcode projects General settings. Add MPQRScanSDK.xcframework in Frameworks, Libraries and Embedded content.

### Objective C {#objective-c}

Follow the same instructions as Swift.

### Generate QR Code {#generate-qr-code-1}

Use the following function to generate a QR sample code:

**Swift**

```Swift
import CoreImage

func generateQRCode(from string: String) -> UIImage? {
  let data = string.data(using: String.Encoding.utf8)

  if let filter = CIFilter(name: "CIQRCodeGenerator") {
    filter.setValue(data, forKey: "inputMessage")
    // Set scale according to your device display. If the qr code is blurry then increase scale
    let transform = CGAffineTransform(scaleX: 3, y: 3)

    if let output = filter.outputImage?.transformed(by: transform) {
        return UIImage(ciImage: output)
    }
  }
  return nil
}

func generatePushPaymentQR() {
  // Generate
  let pushPaymentData = PushPaymentData()

  // Payload format indicator
  pushPaymentData.payloadFormatIndicator = "01"

  // Point of initiation method
  pushPaymentData.pointOfInitiationMethod = "12"

  // Additional data
  let addData = AdditionalData()
  addData.storeId = "A6008"
  addData.loyaltyNumber = "***"
  addData.terminalId = "A6008667"
  addData.additionalConsumerDataRequest = "ME"
  pushPaymentData.additionalData = addData

  let mastercardData = MastercardData()
  let recipentIdCheckout = "623456a8-1c34-1b34-34b4-123abbc234ef"
  let srcDpaId = "123456a8-1c34-1b34-34b4-123abbc234ef"
  do {
    try mastercardData.setSRCID(recipentIdCheckout, withSrcDpaId: srcDpaId)
    try pushPaymentData.setMastercard(mastercardData)
  } catch {
    print("Error occurred while adding mastercardData \(error)")
  }

  // Merchant category code
  pushPaymentData.merchantCategoryCode = "1434"

  // Transaction currency code
  pushPaymentData.transactionCurrencyCode = "156"

  // Transaction amount
  pushPaymentData.transactionAmount = "83.80"

  // Country code
  pushPaymentData.countryCode = "CN"

  // Merchant name
  pushPaymentData.merchantName = "BEST TRANSPORT"

  // Merchant city
  pushPaymentData.merchantCity = "BEIJING"

  // Postal code
  pushPaymentData.postalCode = "56748"

  var qrCodeString: String?
  do {
    // Genarate QR code string
    qrCodeString = try pushPaymentData.generatePushPaymentString()
    print("QR code string \(qrCodeString)")

    // Generate image
    let image = generateQRCode(from: qrCodeString!)
  } catch {
    print("Error occurred while generating QR code string \(error)")
    return
  }
}
```

**Objective-C**

```Objective-C
#import <MPQRCoreSDK/MPQRCoreSDK.h>

- (UIImage *)generateQRCode:(NSString *)string {
    NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
    CIFilter *filter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
    if (!filter || !data)
        return nil;

    [filter setValue:data forKey:@"inputMessage"];
    CGAffineTransform transform = CGAffineTransformMakeScale(3, 3);
    CIImage *image = [[filter outputImage] imageByApplyingTransform:transform];
    return [UIImage imageWithCIImage:image];
}


-(void)generatePushPaymentQR{
    // Generate
    PushPaymentData *pushPaymentData = [[PushPaymentData alloc] init];

    // Payload format indicator
    pushPaymentData.payloadFormatIndicator = @"01";

    // Point of initiation method
    pushPaymentData.pointOfInitiationMethod = @"12";

    MPQRError* error;

    AdditionalData* addData = [AdditionalData new];
    addData.storeId = @"A6008";
    addData.loyaltyNumber = @"****";
    addData.terminalId = @"A6008667";
    addData.additionalConsumerDataRequest = @"ME";
    pushPaymentData.additionalData = addData;

    // MastercardData for tag 05
    MastercardData *masterCardData = [MastercardData new];
    NSString* srcDpaId = @"62345678-1234-1234-1234-123456781acf";
    NSString* recipientIdCheckout = @"12345678-1234-1234-1234-123456781acf";
    [masterCardData setSRCID:recipientIdCheckout withSrcDpaId:srcDpaId error:&error];
    if (!error) {
        [pushPaymentData setMastercardData:masterCardData error:&error];
    }

    // Merchant category code
    pushPaymentData.merchantCategoryCode = @"1434";

    // Transaction currency code
    pushPaymentData.transactionCurrencyCode = @"156";

    // Transaction amount
    pushPaymentData.transactionAmount = @"83.80";

    // Country code
    pushPaymentData.countryCode = @"CN";

    // Merchant name
    pushPaymentData.merchantName = @"BEST TRANSPORT";

    // Merchant city
    pushPaymentData.merchantCity = @"BEIJING";

    // Postal code
    pushPaymentData.postalCode = @"56748";

    NSString* strQRCode = [pushPaymentData generatePushPaymentString:&error];
    NSLog(@"QR code string: %@", strQRCode);
    if (error) {
        NSLog(@"Error: %@", error);
    } else {
        // Generate image
        UIImage *image = [self generateQRCode: strQRCode];
    }
}
```

## iOS QR Scan SDK {#ios-qr-scan-sdk}

### Installation {#installation-1}

#### Swift {#swift-1}

1. Download the latest release of MPQR Scan SDK. [MPQRScanSDK.xcframework.zip](https://static.developer.mastercard.com/content/mastercard-checkout-solutions/uploads/MPQRScanSDK.xcframework.zip) (527KB)
2. Unzip the file and place it in the project folder.
3. Go to Xcode projects General settings. Add MPQRScanSDK.xcframework in Frameworks, Libraries and Embedded content.

#### Objective C {#objective-c-1}

Follow the same instructions as Swift.

#### Subclass of QRCodeReaderViewController {#subclass-of-qrcodereaderviewcontroller}

**Swift**

```Swift
import UIKit
import MPQRScanSDK

class QRCodeReaderViewControllerSubClass: QRCodeReaderViewController {

  override func setupUIComponents(withCancelButtonTitle cancelButtonTitle: String?, cameraView: QRCodeReaderView?) {
    if let cameraView = cameraView {
      self.cameraView = cameraView;
    }else
    {
      self.cameraView = QRCodeReaderView()
    }

    // Customized Camera view
    let overlayView = self.cameraView!.getOverlay()
    overlayView.cornerColor = UIColor.green
    overlayView.cornerWidth = 6
    overlayView.cornerLength = 75
    overlayView.indicatorSize = CGSize(width: 250, height: 250)
    view.addSubview(self.cameraView!)

    // Customized Cancel Button
    if cancelButtonTitle != nil, self.showCancelButton {
      self.cancelButton = UIButton.init();
      if let cancelButton = self.cancelButton {
        cancelButton.translatesAutoresizingMaskIntoConstraints = false
        // Developer can customize image, title and other attributes for button
        cancelButton.setTitle(cancelButtonTitle, for: .normal)
        cancelButton.setTitleColor(UIColor.yellow, for: .normal)
        cancelButton.addTarget(self, action: #selector(clickedCancel), for: .touchUpInside)
        view.addSubview(cancelButton)
      }
    }

    // Customize Toggle Torch Button
    if showTorchButton == true, codeReader?.isTorchAvailable() == true {
      self.toggleTorchButton = UIButton.init()
      if let toggleTorchBtn = self.toggleTorchButton {
        toggleTorchBtn.translatesAutoresizingMaskIntoConstraints = false
        // Developer can customize image, title and other attributes for button
        toggleTorchBtn.setImage(UIImage.init(named: "torchBtn"), for: .normal)
        toggleTorchBtn.addTarget(self, action: #selector(clickedToggleTorch), for: .touchUpInside)
        view.addSubview(toggleTorchBtn)
    }
  }
}

// Handle Cancel button click event
@objc private func clickedCancel() {
  self.dismiss(animated: true, completion: nil)
}

// Handle Toggle torch button click event
@objc private func clickedToggleTorch() {
  codeReader?.toggleTorch()
}

override func setupAutoLayoutConstraints() {
  if self.cancelButton != nil {
    // view constraints if cancel button is present
    let views = ["cameraView":self.cameraView!, "cancelButton":self.cancelButton!]
    view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[cameraView][cancelButton(40)]|", options: NSLayoutConstraint.FormatOptions(rawValue: 0), metrics: nil, views: views))
    view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-50-[cameraView]-50-|", options: NSLayoutConstraint.FormatOptions(rawValue: 0), metrics: nil, views: views))
    view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-50-[cancelButton]-50-|", options: NSLayoutConstraint.FormatOptions(rawValue: 0), metrics: nil, views: views))
  }else{
    // view constraints if cancel button is absent
    let views = ["cameraView":self.cameraView!]
    view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-50-[cameraView]-50-|", options: NSLayoutConstraint.FormatOptions(rawValue: 0), metrics: nil, views: views))
    view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-50-[cameraView]-50-|", options: NSLayoutConstraint.FormatOptions(rawValue: 0), metrics: nil, views: views))
  }

    if self.toggleTorchButton != nil {
      // toggleTorchButton constraints for iOS 11+ and below
      if #available(iOS 11.0, *) {
        NSLayoutConstraint.activate([
          self.toggleTorchButton!.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor, constant: 30),
          self.toggleTorchButton!.leadingAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.leadingAnchor, constant: 10)
        ])
      } else {
        let topLayoutGuide = self.topLayoutGuide;
        let views = ["toggleTorchButton":self.toggleTorchButton!, "topLayoutGuide": topLayoutGuide] as [String : Any]
        view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:[topLayoutGuide]-[toggleTorchButton(50)]", options: NSLayoutConstraint.FormatOptions(rawValue: 0), metrics: nil, views: views))
        view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[toggleTorchButton(70)]", options: NSLayoutConstraint.FormatOptions(rawValue: 0), metrics: nil, views: views))
      }
    }
  }
}
```

**Objective-C**

```Objective-C
#import <UIKit/UIKit.h>
#import <MPQRScanSDK/MPQRScanSDK.h>

@interface QRCodeReaderViewControllerSubClass : QRCodeReaderViewController

@end

@implementation QRCodeReaderViewControllerSubClass

#pragma mark - Overriden

- (void)setupUIComponentsWithCancelButtonTitle:(NSString *)cancelButtonTitle cameraView:(QRCodeReaderView *)cameraView{
  self.cameraView = cameraView;
  if (!self.cameraView) {
    self.cameraView = [[QRCodeReaderView alloc] init];
    self.cameraView.translatesAutoresizingMaskIntoConstraints = NO;
    self.cameraView.clipsToBounds = YES;
  }

  // Customized Camera view
  QRCodeReaderViewOverlay *overlayView = (QRCodeReaderViewOverlay *)[self.cameraView getOverlay];
  overlayView.cornerColor = UIColor.greenColor;
  overlayView.cornerWidth = 6;
  overlayView.cornerLength = 75;
  overlayView.indicatorSize = CGSizeMake(250, 250);
  [self.view addSubview:self.cameraView];

  // Customized Cancel Button
  if (self.showCancelButton) {
    self.cancelButton = [[UIButton alloc] init];
    self.cancelButton.translatesAutoresizingMaskIntoConstraints = NO;
    // Developer can customize image, title and other attributes for button
    [self.cancelButton setTitle:cancelButtonTitle forState:UIControlStateNormal];
    [self.cancelButton setTitleColor:[UIColor yellowColor] forState:UIControlStateNormal];
    [self.cancelButton addTarget:self action:@selector(clickedCancel) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview: self.cancelButton];
  }

  // Customize Toggle Torch Button
  if (self.showTorchButton) {
    self.toggleTorchButton = [[UIButton alloc] init];
    self.toggleTorchButton.translatesAutoresizingMaskIntoConstraints = NO;
    // Developer can customize image, title and other attributes for button
    [self.toggleTorchButton setImage:[UIImage imageNamed:@"torchBtn"] forState:UIControlStateNormal];
    [self.toggleTorchButton addTarget:self action:@selector(clickedToggleTorch) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview: self.toggleTorchButton];
  }
}

// Handle Cancel button click event
- (void)clickedCancel{
    [self dismissViewControllerAnimated:YES completion:nil];
}

// Handle Toggle torch button click event
- (void)clickedToggleTorch{
    [self.codeReader toggleTorch];
}

- (void)setupAutoLayoutConstraints
{
  if (self.cancelButton) {
    // view constraints if cancel button is present
    NSDictionary *views = [NSDictionary dictionaryWithObjectsAndKeys:self.cameraView, @"cameraView", self.cancelButton, @"cancelButton", nil];
    [self.view addConstraints:
     [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[cameraView][cancelButton(40)]|" options:0 metrics:nil views:views]];
    [self.view addConstraints:
     [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[cameraView]|" options:0 metrics:nil views:views]];
    [self.view addConstraints:
     [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[cancelButton]-|" options:0 metrics:nil views:views]];
  }else {
    // view constraints if cancel button is absent
    NSDictionary *views = [NSDictionary dictionaryWithObjectsAndKeys:@"cameraView", self.cameraView, nil];
    [self.view addConstraints:
     [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[cameraView]|" options:0 metrics:nil views:views]];
    [self.view addConstraints:
     [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[cameraView]|" options:0 metrics:nil views:views]];
  }

  if (self.toggleTorchButton != nil) {
    // toggleTorchButton constraints for iOS 11+ and below
    if (@available(iOS 11.0, *)) {
      [[[self.toggleTorchButton topAnchor] constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor constant:30] setActive: YES];
      [[[self.toggleTorchButton leadingAnchor] constraintEqualToAnchor:self.view.safeAreaLayoutGuide.leadingAnchor constant:10] setActive: YES];
    } else {
      id topLayoutGuide = self.topLayoutGuide;
      NSDictionary *torchViews = [NSDictionary dictionaryWithObjectsAndKeys:self.toggleTorchButton, @"toggleTorchButton", topLayoutGuide, @"topLayoutGuide", nil];
      [self.view addConstraints:
       [NSLayoutConstraint constraintsWithVisualFormat:@"V:[topLayoutGuide]-[toggleTorchButton(50)]" options:0 metrics:nil views:torchViews]];
      [self.view addConstraints:
       [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[toggleTorchButton(70)]" options:0 metrics:nil views:torchViews]];
    }

  }
}

@end
```

## QR Tester Application {#qr-tester-application}

The following Android QR tester application can be used to generate and test EMVCo-compliant SQR QR codes.

**Android reference tester application:**
[TesterTool-release.apk](https://static.developer.mastercard.com/content/mastercard-checkout-solutions/uploads/TesterTool-release.apk) (4MB)
