Native Pay Methods

Apple Pay

In the Flutter SDK, Apple Pay can be used to process payments with a smooth, native experience. Before displaying the Apple Pay sheet, it is essential to:

  1. Configure Apple Pay (optionally) to collect billing data.
  2. Ensure that the device supports Apple Pay.
  3. Decide which approach to use for processing payments.

1. (Optional) Configuring Apple Pay to Collect Billing Data

If you need to collect specific billing data from the user during the payment process and use it as part of the billing data, you can configure the collectibleBillingData accordingly.

import 'package:moneyhash/moneyhash.dart';

void main() {
  // Create a custom Apple Pay configuration
  final applePayConfig = ApplePayConfiguration(
    collectibleBillingData: [CollectibleBillingData.email], 
  );

  // Initialize the SDK with the custom Apple Pay configuration
  final moneyHash = MoneyHashSDKBuilder()
    .setNativeApplePayConfig(applePayConfig)
    .build();

  print("MoneyHash SDK initialized with Apple Pay configuration.");
}
  • collectibleBillingData is a list of CollectibleBillingData enums. Currently, only CollectibleBillingData.email is available.
  • To disable billing data collection, you can pass an empty list [].

2. Check if the Device is Compatible with Apple Pay

Before attempting to show the Apple Pay sheet, confirm that the device supports Apple Pay by calling:

final isCompatible = await moneyHash.isDeviceCompatibleWithApplePay();

if (isCompatible) {
  // Proceed with Apple Pay
} else {
  // Handle case where the device is not compatible
  print("This device does not support Apple Pay");
}

🚧

Note: This feature is only supported on iOS devices. Calling this method on other platforms will throw an UnsupportedError.


Approaches for Apple Pay Payments

You can handle Apple Pay payments in two different ways:

  1. Approach #1: Directly use proceedWithApplePay (requires an intentId upfront).
  2. Approach #2: Generate an Apple Pay receipt first, then submit that receipt separately (no intentId initially required).

Approach #1: Direct Payment with proceedWithApplePay

If you already have your intentId, you can directly display the Apple Pay sheet and complete the payment in one step using proceedWithApplePay.

Retrieve Apple Pay Data from NativePay State

When handling an intent state, you may receive a NativePay state that includes an ApplePayData object. It typically contains:

  • merchantId: The Apple Pay merchant identifier
  • countryCode: The country code for the payment
  • currencyCode: The currency code for the payment
  • amount: The total amount for the payment

These values can be passed into proceedWithApplePay.

Code Example:

if (intentState is NativePay) {
  final applePayData = intentState.nativePayData as ApplePayData?;

  if (applePayData != null) {
    try {
      final intentId = "<intent_id>"; // Unique identifier for the payment intent
      final depositAmount = applePayData.amount ?? 0.0;
      final merchantIdentifier = applePayData.merchantId ?? "merchant.com.example";
      final currencyCode = applePayData.currencyCode ?? "USD";
      final countryCode = applePayData.countryCode ?? "US";

      // Display Apple Pay sheet and process payment
      final IntentDetails? intentDetails = await moneyHash.proceedWithApplePay(
        intentId,
        depositAmount,
        merchantIdentifier,
        currencyCode,
        countryCode,
      );

      if (intentDetails != null) {
        // Handle successful payment
        print("Payment completed successfully: $intentDetails");
      } else {
        // Handle case where no result is returned
        print("Payment was cancelled or no result was returned.");
      }
    } on MHException catch (e) {
      // Handle any Apple Pay errors
      print("Error during Apple Pay: ${e.message}");
    }
  } else {
    print("No Apple Pay data available in NativePay state.");
  }
}
  • This displays the Apple Pay sheet to the user, processes the payment, and returns IntentDetails on success or throws an error (MHException) if something goes wrong.
  • If billing data is required but not configured or available, the SDK will throw an error prompting you to supply the needed data.

Approach #2: Generate a Receipt First, Then Submit the Receipt

This new approach does not require an intentId up front. Instead, you generate an Apple Pay receipt, and once you have or create an intentId, you submit that receipt.

Step 1: Generate the Apple Pay Receipt

Use generateApplePayReceipt to show the Apple Pay sheet, collect payment data, and generate a NativePayReceipt without requiring an intentId:

if (intentState is NativePay) {
  final applePayData = intentState.nativePayData as ApplePayData?;

  if (applePayData != null) {
    try {
      // Extract payment details from applePayData
      final depositAmount = applePayData.amount ?? 0.0;
      final merchantIdentifier = applePayData.merchantId ?? "merchant.com.example";
      final currencyCode = applePayData.currencyCode ?? "USD";
      final countryCode = applePayData.countryCode ?? "US";

      // Show Apple Pay sheet and generate the receipt
      final NativePayReceipt? receipt = await moneyHash.generateApplePayReceipt(
        depositAmount,
        merchantIdentifier,
        currencyCode,
        countryCode,
      );

      if (receipt != null) {
        print("Apple Pay Receipt generated successfully: $receipt");
        // Store 'receipt' until you're ready to submit the payment
      } else {
        print("Apple Pay receipt generation was cancelled.");
      }
    } on MHException catch (e) {
      // Handle any Apple Pay errors
      print("Error generating Apple Pay receipt: ${e.message}");
    }
  } else {
    print("No Apple Pay data available in NativePay state.");
  }
}

💡

Important: The generated NativePayReceipt is only valid for a short period. Make sure to submit it promptly once you have the intentId.

Step 2: Submit the Payment Receipt

After generating the NativePayReceipt, use submitPaymentReceipt to finalize the payment. This method requires an intentId.

try {
  final intentId = "<intent_id>"; // Obtain or generate this after receipt creation

  // Submit the receipt to complete the payment
  final IntentDetails? intentDetails = await moneyHash.submitPaymentReceipt(
    intentId,
    receipt,
  );

  if (intentDetails != null) {
    print("Payment completed successfully: $intentDetails");
  } else {
    print("Payment was cancelled or no result was returned.");
  }
} on MHException catch (e) {
  // Handle error during payment submission
  print("Error submitting payment receipt: ${e.message}");
}

📘

If billing data is required but not provided, the SDK will throw an MHException prompting you to supply the necessary information before completing the payment.


Google Pay

(No changes from your original text are required here, since the question specifically requested Apple Pay documentation updates. The Google Pay documentation remains as provided.)


Summary

  1. Configure (Optional): Call setNativeApplePayConfig(...) in MoneyHashSDKBuilder to specify any billing data Apple Pay may collect (e.g., email).
  2. Check Compatibility: Always verify that the device supports Apple Pay using isDeviceCompatibleWithApplePay().
  3. Approach #1 (Direct): If you already have an intentId, use proceedWithApplePay to handle everything in one go.
  4. Approach #2 (Two-Step): If you don’t have an intentId initially or want to separate generation of the Apple Pay receipt from final payment submission, use generateApplePayReceipt first, then call submitPaymentReceipt once you have the intentId.

By following these steps, you can integrate Apple Pay into your Flutter application using the MoneyHash SDK, providing users with a seamless and secure payment experience.