Shopify / mobile-buy-sdk-ios

Shopify’s Mobile Buy SDK makes it simple to sell physical products inside your mobile app. With a few lines of code, you can connect your app with the Shopify platform and let your users buy your products using Apple Pay or their credit card.
MIT License
452 stars 198 forks source link

Apple Pay 13.1.0 -> cartPaymentUpdate #1247

Open fengcart opened 1 week ago

fengcart commented 1 week ago

I'm using latest MobileBuy but seems I'm not able to create an order on shopify after I successfully do a purchase order on Apple Pay. My goal is to create an order on shopify so the user that already paid using Apple Pay can have the order created on Shopify but seems this is not working and there is no other way to do this AFAIk. Please explain if this is ok and why it's not working. Thanks in advice. I'm dealing with this since at least 2 weeks.


    /// APPLE PAY
    func completeCheckoutWithApplePay(checkout: CheckoutViewModel,
                                      billingAddress: PKContact,
                                      token: String,
                                      idempotencyToken: String,
                                      data: String,
                                      header: Storefront.ApplePayWalletHeaderInput,
                                      signature: String,
                                      version: String,
                                      last4Digits: String,
                                      completion: @escaping (CheckoutAppleResult) -> Void) {

        let mutation = ClientQuery.mutationForCompleteCheckoutUsingApplePay(checkout: checkout, billingAddress: billingAddress,
                                                                            token: token,
                                                                            idempotencyToken: idempotencyToken,
                                                                            data: data,
                                                                            header: header,
                                                                            signature: signature,
                                                                            version: version, 
                                                                            last4Digits: last4Digits)

        let task = self.client.mutateGraphWith(mutation) { response, error in

            if let errors = response?.cartPaymentUpdate?.userErrors {
                for userError in errors {
                    print("Field: \(userError.field), Message: \(userError.message)")
                }
            }

            if let error = error {
                print("GraphQL Error: \(error.localizedDescription)")
                completion(.failure("GraphQL error: \(error.localizedDescription)"))
                return
            }

            if let cart = response?.cartPaymentUpdate?.cart {
                print("Cart updated successfully, fetching order details...\(cart)")

                self.fetchCompletedPayment(cart.id.rawValue) { order in

                    if let order = order {
                        print("Order ID: \(order.id)")
                        completion(.success(order))
                    } else if let userErrors = response?.cartPaymentUpdate?.userErrors, !userErrors.isEmpty {
                        let errorMessage = userErrors.map { $0.message }.joined(separator: ", ")
                        print("User Errors from cartPaymentUpdate: \(errorMessage)")
                        //completion(.failure("cartPaymentUpdate error: \(errorMessage)"))

                        let errorMessage2 = userErrors.first?.message ?? "Unknown error"
                        print("cartPaymentUpdate error: \(errorMessage2)")
                        completion(.failure(errorMessage2))
                    } else {
                        completion(.failure("Failed to fetch order ID"))
                    }

                }
            } else {
                print("Error completing cartPaymentUpdate")
                completion(.failure("Failed to complete cartPaymentUpdate"))
            }
        }
        task.resume()

    }

//// CLIENT
static func mutationForCompleteCheckoutUsingApplePay(
        checkout: CheckoutViewModel,
        billingAddress: PKContact,
        token: String,
        idempotencyToken: String,
        data: String,
        header: Storefront.ApplePayWalletHeaderInput,
        signature: String,
        version: String,
        last4Digits: String
    ) -> Storefront.MutationQuery {

        let postalAddress = billingAddress.postalAddress

        let mailingAddress = Storefront.MailingAddressInput.create(
            address1: Input.value(postalAddress?.street),  // Calle
            address2: Input.value(""), // Puedes mapear cualquier campo adicional aquí si es necesario
            city: Input.value(postalAddress?.city), // Ciudad
            country: Input.value(postalAddress?.isoCountryCode), // Código ISO del país
            firstName: Input.value(billingAddress.name?.givenName ?? ""), // Primer nombre
            lastName: Input.value(billingAddress.name?.familyName ?? ""), // Apellido
            province: Input.value(postalAddress?.state), // Provincia o Estado
            zip: Input.value(postalAddress?.postalCode) // Código postal
        )

        let currencyCode = Storefront.CurrencyCode(rawValue: checkout.currencyCode)!
        let paymentAmount = Storefront.MoneyInput(amount: checkout.paymentDue, currencyCode: currencyCode)

        let applePayContent = Storefront.ApplePayWalletContentInput.create(
            billingAddress: mailingAddress,
            data: data,
            header: header,
            signature: signature,
            version: version,
            lastDigits: Input.value(last4Digits)
        )

        let paymentInput = Storefront.CartPaymentInput.create(
            amount: paymentAmount,
            walletPaymentMethod: .value(Storefront.CartWalletPaymentMethodInput.create(
                applePayWalletContent: .value(applePayContent)
            ))
        )

        let mutation = Storefront.buildMutation { $0
            .cartPaymentUpdate(cartId: GraphQL.ID(rawValue: checkout.id), payment: paymentInput) { $0
                .userErrors { $0
                    .field()
                    .message()
                }
                .cart { $0
                    .id()
                }
            }
        }

        return mutation
    }

But I'm getting every time the same error

GraphQL Error: No se ha podido completar la operación. (Error de Buy.Graph.QueryError 4.) Failed paymentAuthorizationViewController: GraphQL error: No se ha podido completar la operación. (Error de Buy.Graph.QueryError 4.)