Hello,
I'm implementing the wallet extension but I found a problem in the passEntries function. This following part is giving nil ando I don't know why
if let entry = PKIssuerProvisioningExtensionPaymentPassEntry( identifier: element.id, title: element.cardType ?? "Card", art: self.testImage()!, addRequestConfiguration: config! ) { entries.append(entry) }
I debug and all the arguments have information but it doesn't create the entry
Hi @MonzGomz,
You wrote:
I'm implementing the wallet extension but I found a problem in the passEntries function. This following part is giving nil ando I don't know why [...]
This is a common pain point with PKIssuerProvisioningExtensionPaymentPassEntry since its initializer silently returns nil without any error. However, there are a few common scenarios to investigate when this occurs:
- Image size and format requirements
- Missing required fields in
PKAddPaymentPassRequestConfiguration - Card already exists in the user's pass library
- Debugging with known-to-be valid hardcoded values
- Verify entitlements
I'll explain more about each scenario below:
(1) Image size and format requirements
Wallet is very strict about card art. The image must meet specific requirements:
- Dimensions: 1526 x 969 px (or at minimum the correct aspect ratio (~1.586:1))
- Type: The parameter expects a
CGImage, not aUIImage.
If testImage() returns a UIImage, make sure you're passing .cgImage:
// ❌ Wrong - passing UIImage directly (won't even compile if types match but wrong semantics)
art: self.testImage()!
// ✅ Correct
art: self.testImage()!.cgImage! // UIImage -> CGImage
Also double check the actual pixel dimensions of your test image. A small or oddly-sized image will cause the init to return nil.
(2) Missing required fields in PKAddPaymentPassRequestConfiguration
Even with config being non-nil, the configuration itself might be incomplete. Make sure all required fields are set:
// ECC_V2 configuration
let config = PKAddPaymentPassRequestConfiguration(encryptionScheme: .ECC_V2)
config?.cardholderName = "John Doe" // Required
config?.primaryAccountSuffix = "1234" // Required - last 4 digits
config?.paymentNetwork = .visa // Required
config?.primaryAccountIdentifier = "..." // Unique card identifier
config?.localizedDescription = "My Card"
The initializer returns nil if any of these required fields are empty or invalid.
(3) Card already exists in Wallet
If primaryAccountIdentifier matches a card already provisioned in the user's pass library, PassKit will rejected it and return nil. You can verify this by checking:
let library = PKPassLibrary()
let existingPasses = library.passes()
// Check if your identifier is already included
(4) Debugging with known-to-be-valid hardcoded values
Try hardcoding everything with known-good values to isolate which argument is the problem:
let testConfig = PKAddPaymentPassRequestConfiguration(encryptionScheme: .ECC_V2)!
testConfig.cardholderName = "Test User"
testConfig.primaryAccountSuffix = "4242"
testConfig.paymentNetwork = .visa
// Use a known valid CGImage (e.g., from a 1536x969 asset)
let testArt = UIImage(named: "card_art_1536x969")!.cgImage!
if let entry = PKIssuerProvisioningExtensionPaymentPassEntry(
identifier: "test-unique-id-123",
title: "Test Card",
art: testArt,
addRequestConfiguration: testConfig
) {
print("Entry created successfully")
} else {
print("Still nil - check entitlements")
}
(5) Verify entitlements
Make sure your extension has the proper entitlement in its .entitlements file:
<key>com.apple.developer.pass-type-identifiers</key>
<array>
<string>pass.com.yourcompany.*</string>
</array>
Note: The wallet extension also needs com.apple.developer.payment-pass-provisioning entitlement, which requires explicit approval from Apple. To learn more, see below:
Requesting Entitlement and Allow Listing
To request the In-App Provisioning Entitlement and allow listing for the issuer app, please apply through the dedicated Submission Form here:
https://developer.apple.com/contact/request/apple-pay-in-app-provisioning/
Important: Only Account Holders can access this form. If you are unable to access, you will need to coordinate with the Account Holder of your team in order to formally submit.
Cheers,
Paris X Pinkney | WWDR | DTS Engineer