0

I'm doing a proof of concept for doing Payments with Siri.

I've got everything working except Siri always says dollar instead of euro. I literally say Send 5 euro to Tim. But siri makes dollar out of it.

This is my code:

class SendPaymentIntentHandler: NSObject, INSendPaymentIntentHandling {

    func handle(sendPayment intent: INSendPaymentIntent, completion: @escaping (INSendPaymentIntentResponse) -> Void) {

        if let payee = intent.payee, let currencyAmount = intent.currencyAmount {
            print("CurrencyAmount \(currencyAmount.amount) currencyCode \(currencyAmount.currencyCode)")

            let bundle = Bundle(for: SendPaymentIntentHandler.self)
            let bundleIdentifier = bundle.object(forInfoDictionaryKey: "CFBundleIdentifier") as? String ?? "KBCPaymentIntent"
            print("BundleIdentifier \(bundleIdentifier)")

            let activity = NSUserActivity.init(activityType: bundleIdentifier)
            let response = INSendPaymentIntentResponse(code: .success, userActivity: activity)
            let paymentRecord = INPaymentRecord(payee: payee, payer: nil, currencyAmount: currencyAmount, paymentMethod: nil, note: intent.note, status: .pending)
            response.paymentRecord = paymentRecord

            completion(response)
        } else {
            // TODO what do we need to do?
            print("Handle Failed")
            completion(INSendPaymentIntentResponse.init(code: .failure, userActivity: nil))
        }
    }

    func resolvePayee(forSendPayment intent: INSendPaymentIntent, with completion: @escaping (INPersonResolutionResult) -> Void) {
        if let payee = intent.payee {
            print("User to pay DISPLAYNAME: \(payee.displayName) FAMILYNAME: \(payee.nameComponents?.familyName ?? "not set") GIVENNAME: \(payee.nameComponents?.givenName ?? "Not set")")
            let recipientMatched = self.inPerson()
            completion(INPersonResolutionResult.success(with: recipientMatched))
        }
    }

    func resolveCurrencyAmount(forSendPayment intent: INSendPaymentIntent, with completion: @escaping (INCurrencyAmountResolutionResult) -> Void) {
        if let amount = intent.currencyAmount?.amount {
            // TODO check if it's always EUR
            print("Amount is resolved")
            completion(INCurrencyAmountResolutionResult.success(with: INCurrencyAmount(amount: amount, currencyCode: "EUR")))
        } else {
            print("Amount is not resolved")
            completion(INCurrencyAmountResolutionResult.success(with: INCurrencyAmount(amount: NSDecimalNumber.zero, currencyCode: "EUR")))
        }
    }

    public func inPerson() -> INPerson {
        let nameFormatter = PersonNameComponentsFormatter()

        if let nameComponents = nameFormatter.personNameComponents(from: "Tim") {
            let personHandle = INPersonHandle(value: "dd", type: .phoneNumber)
            let person = INPerson.init(personHandle: personHandle, nameComponents: nameComponents, displayName: "Tim", image: nil, contactIdentifier: nil, customIdentifier: nil)

            return person
        } else {
            let personHandle = INPersonHandle(value: "dd", type: .phoneNumber)
            let person = INPerson.init(personHandle: personHandle, nameComponents: nil, displayName: "Tim", image: nil, contactIdentifier: nil, customIdentifier: nil)
            return person
        }
    }
}

Does someone know what I'm doing wrong?

user1007522
  • 7,858
  • 17
  • 69
  • 113
  • I think it depends on the region you set in the settings. I tried asking Siri, how much is a euro, it replied with the value in Rupees, Indian Currency. – Sachin Vas Feb 16 '17 at 09:25

2 Answers2

3

I found the solution.

After the resolveCurrencyAmount method you need to confirm it like this:

func confirm(sendPayment intent: INSendPaymentIntent, completion: @escaping (INSendPaymentIntentResponse) -> Void) {
    print("Confirm sendPayment intent")
    let response = INSendPaymentIntentResponse(code: .ready, userActivity: nil)
    response.paymentRecord = INPaymentRecord(payee: intent.payee, payer: nil, currencyAmount: intent.currencyAmount, paymentMethod: nil, note: intent.note, status: .pending)

    completion(response)
}

Then it shows the correct currency.

user1007522
  • 7,858
  • 17
  • 69
  • 113
0

You can set currency code in INPaymentMethod class itself.

        let paymentMethod = INPaymentMethod(type: .credit, name: "Visa Platinum", identificationHint: "•••• •••• •••• 1234", icon: INImage(named: "creditCardImage"))
        let applePay = INPaymentMethod.applePay()  // If you support Pay and the user has an Pay payment method set in your parent app
        response.paymentMethods = [ paymentMethod, applePay ]
        paymentMethod.currencyCode = "INR"
Pratik Patel
  • 1,393
  • 12
  • 18