diff --git a/Sources/AppStoreServerLibrary/Models/JWSRenewalInfoDecodedPayload.swift b/Sources/AppStoreServerLibrary/Models/JWSRenewalInfoDecodedPayload.swift index e6db8a0b..d2a8c8e7 100644 --- a/Sources/AppStoreServerLibrary/Models/JWSRenewalInfoDecodedPayload.swift +++ b/Sources/AppStoreServerLibrary/Models/JWSRenewalInfoDecodedPayload.swift @@ -6,7 +6,7 @@ import Foundation ///[JWSRenewalInfoDecodedPayload](https://developer.apple.com/documentation/appstoreserverapi/jwsrenewalinfodecodedpayload) public struct JWSRenewalInfoDecodedPayload: DecodedSignedData, Decodable, Encodable, Hashable { - public init(expirationIntent: ExpirationIntent? = nil, originalTransactionId: String? = nil, autoRenewProductId: String? = nil, productId: String? = nil, autoRenewStatus: AutoRenewStatus? = nil, isInBillingRetryPeriod: Bool? = nil, priceIncreaseStatus: PriceIncreaseStatus? = nil, gracePeriodExpiresDate: Date? = nil, offerType: OfferType? = nil, offerIdentifier: String? = nil, signedDate: Date? = nil, environment: Environment? = nil, recentSubscriptionStartDate: Date? = nil, renewalDate: Date? = nil, currency: String? = nil, renewalPrice: Int64? = nil, offerDiscountType: OfferDiscountType? = nil) { + public init(expirationIntent: ExpirationIntent? = nil, originalTransactionId: String? = nil, autoRenewProductId: String? = nil, productId: String? = nil, autoRenewStatus: AutoRenewStatus? = nil, isInBillingRetryPeriod: Bool? = nil, priceIncreaseStatus: PriceIncreaseStatus? = nil, gracePeriodExpiresDate: Date? = nil, offerType: OfferType? = nil, offerIdentifier: String? = nil, signedDate: Date? = nil, environment: Environment? = nil, recentSubscriptionStartDate: Date? = nil, renewalDate: Date? = nil, currency: String? = nil, renewalPrice: Int64? = nil, offerDiscountType: OfferDiscountType? = nil, eligibleWinBackOfferIds: [String]? = nil) { self.expirationIntent = expirationIntent self.originalTransactionId = originalTransactionId self.autoRenewProductId = autoRenewProductId @@ -24,9 +24,10 @@ public struct JWSRenewalInfoDecodedPayload: DecodedSignedData, Decodable, Encoda self.currency = currency self.renewalPrice = renewalPrice self.offerDiscountType = offerDiscountType + self.eligibleWinBackOfferIds = eligibleWinBackOfferIds } - public init(rawExpirationIntent: Int32? = nil, originalTransactionId: String? = nil, autoRenewProductId: String? = nil, productId: String? = nil, rawAutoRenewStatus: Int32? = nil, isInBillingRetryPeriod: Bool? = nil, rawPriceIncreaseStatus: Int32? = nil, gracePeriodExpiresDate: Date? = nil, rawOfferType: Int32? = nil, offerIdentifier: String? = nil, signedDate: Date? = nil, rawEnvironment: String? = nil, recentSubscriptionStartDate: Date? = nil, renewalDate: Date? = nil, currency: String? = nil, renewalPrice: Int64? = nil, offerDiscountType: OfferDiscountType? = nil) { + public init(rawExpirationIntent: Int32? = nil, originalTransactionId: String? = nil, autoRenewProductId: String? = nil, productId: String? = nil, rawAutoRenewStatus: Int32? = nil, isInBillingRetryPeriod: Bool? = nil, rawPriceIncreaseStatus: Int32? = nil, gracePeriodExpiresDate: Date? = nil, rawOfferType: Int32? = nil, offerIdentifier: String? = nil, signedDate: Date? = nil, rawEnvironment: String? = nil, recentSubscriptionStartDate: Date? = nil, renewalDate: Date? = nil, currency: String? = nil, renewalPrice: Int64? = nil, offerDiscountType: OfferDiscountType? = nil, eligibleWinBackOfferIds: [String]? = nil) { self.rawExpirationIntent = rawExpirationIntent self.originalTransactionId = originalTransactionId self.autoRenewProductId = autoRenewProductId @@ -44,6 +45,7 @@ public struct JWSRenewalInfoDecodedPayload: DecodedSignedData, Decodable, Encoda self.currency = currency self.renewalPrice = renewalPrice self.offerDiscountType = offerDiscountType + self.eligibleWinBackOfferIds = eligibleWinBackOfferIds } ///The reason the subscription expired. @@ -190,6 +192,11 @@ public struct JWSRenewalInfoDecodedPayload: DecodedSignedData, Decodable, Encoda ///See ``offerDiscountType`` public var rawOfferDiscountType: String? + + ///An array of win-back offer identifiers that a customer is eligible to redeem, which sorts the identifiers to present the better offers first. + /// + ///[eligibleWinBackOfferIds](https://developer.apple.com/documentation/appstoreserverapi/eligiblewinbackofferids) + public var eligibleWinBackOfferIds: [String]? public enum CodingKeys: CodingKey { case expirationIntent @@ -209,6 +216,7 @@ public struct JWSRenewalInfoDecodedPayload: DecodedSignedData, Decodable, Encoda case currency case renewalPrice case offerDiscountType + case eligibleWinBackOfferIds } public init(from decoder: any Decoder) throws { @@ -230,6 +238,7 @@ public struct JWSRenewalInfoDecodedPayload: DecodedSignedData, Decodable, Encoda self.currency = try container.decodeIfPresent(String.self, forKey: .currency) self.renewalPrice = try container.decodeIfPresent(Int64.self, forKey: .renewalPrice) self.rawOfferDiscountType = try container.decodeIfPresent(String.self, forKey: .offerDiscountType) + self.eligibleWinBackOfferIds = try container.decodeIfPresent([String].self, forKey: .eligibleWinBackOfferIds) } public func encode(to encoder: any Encoder) throws { @@ -251,5 +260,6 @@ public struct JWSRenewalInfoDecodedPayload: DecodedSignedData, Decodable, Encoda try container.encodeIfPresent(self.currency, forKey: .currency) try container.encodeIfPresent(self.renewalPrice, forKey: .renewalPrice) try container.encodeIfPresent(self.rawOfferDiscountType, forKey: .offerDiscountType) + try container.encodeIfPresent(self.eligibleWinBackOfferIds, forKey: .eligibleWinBackOfferIds) } } diff --git a/Sources/AppStoreServerLibrary/Models/OfferType.swift b/Sources/AppStoreServerLibrary/Models/OfferType.swift index e687f0c0..7a558529 100644 --- a/Sources/AppStoreServerLibrary/Models/OfferType.swift +++ b/Sources/AppStoreServerLibrary/Models/OfferType.swift @@ -7,4 +7,5 @@ public enum OfferType: Int32, Decodable, Encodable, Hashable { case introductoryOffer = 1 case promotionalOffer = 2 case subscriptionOfferCode = 3 + case winBackOffer = 4 } diff --git a/Tests/AppStoreServerLibraryTests/SignedModelTests.swift b/Tests/AppStoreServerLibraryTests/SignedModelTests.swift index f0f16de6..e3733915 100644 --- a/Tests/AppStoreServerLibraryTests/SignedModelTests.swift +++ b/Tests/AppStoreServerLibraryTests/SignedModelTests.swift @@ -248,6 +248,7 @@ final class SignedModelTests: XCTestCase { XCTAssertEqual("USD", renewalInfo.currency) XCTAssertEqual(OfferDiscountType.payAsYouGo, renewalInfo.offerDiscountType) XCTAssertEqual("PAY_AS_YOU_GO", renewalInfo.rawOfferDiscountType) + XCTAssertEqual(["eligible1", "eligible2"], renewalInfo.eligibleWinBackOfferIds) TestingUtility.confirmCodableInternallyConsistent(renewalInfo) } diff --git a/Tests/AppStoreServerLibraryTests/resources/models/signedRenewalInfo.json b/Tests/AppStoreServerLibraryTests/resources/models/signedRenewalInfo.json index 9868ad4f..30b90d27 100644 --- a/Tests/AppStoreServerLibraryTests/resources/models/signedRenewalInfo.json +++ b/Tests/AppStoreServerLibraryTests/resources/models/signedRenewalInfo.json @@ -15,5 +15,9 @@ "renewalDate": 1698148850000, "renewalPrice": 9990, "currency": "USD", - "offerDiscountType": "PAY_AS_YOU_GO" + "offerDiscountType": "PAY_AS_YOU_GO", + "eligibleWinBackOfferIds": [ + "eligible1", + "eligible2" + ] }