Android ödeme uygulamasından kargo ve iletişim bilgilerini sağlama

Kargo adresini ve ödeyenin iletişim bilgilerini Web Payments API'leri ile sağlamak için Android ödeme uygulamanızı güncelleme

Sahel Sharify
Sahel Sharify

Yayınlanma tarihi: 17 Temmuz 2020, Son güncelleme tarihi: 27 Mayıs 2025

Kargo adresini ve iletişim bilgilerini bir web formu aracılığıyla girmek, müşteriler için zahmetli bir deneyim olabilir. Bu durum hatalara ve dönüşüm oranının düşmesine neden olabilir.

Bu nedenle, Ödeme İsteği API'si, kargo adresi ve iletişim bilgilerinin istenmesini destekler. Bu durum birden fazla avantaj sağlar:

  • Kullanıcılar yalnızca birkaç dokunuşla doğru adresi seçebilir.
  • Adres her zaman standartlaştırılmış biçimde döndürülür.
  • Yanlış adres gönderme olasılığı daha düşüktür.

Tarayıcılar, birleşik bir ödeme deneyimi sunmak için kargo adresi ve iletişim bilgilerinin toplanmasını ödeme uygulamasına erteleyebilir. Bu işlevin adı yetki devretme'dir.

Chrome, mümkün olduğunda müşterinin kargo adresinin ve iletişim bilgilerinin toplanmasını çağrılan Android ödeme uygulamasına devreder. Bu devretme, ödeme sırasında yaşanan sorunları azaltır.

Satıcı web sitesi, müşterinin kargo adresi ve kargo seçimine bağlı olarak kargo seçeneklerini ve toplam fiyatı dinamik olarak güncelleyebilir.

Kargo seçeneği ve kargo adresi değişikliği yapılıyor. Bu seçeneğin kargo seçeneklerini ve toplam fiyatı nasıl dinamik olarak etkilediğini görün.

Halihazırda mevcut bir Android ödeme uygulamasına temsilci desteği eklemek için aşağıdaki adımları uygulayın:

  1. Desteklenen temsil işlemlerini bildirin.
  2. Gerekli ödeme seçenekleri için Parse PAY intent ekstralarını kullanın.
  3. Ödeme yanıtında gerekli bilgileri sağlayın.
  4. İsteğe bağlı: Dinamik akışı destekleme:
    1. Kullanıcının seçtiği ödeme yönteminde, kargo adresinde veya kargo seçeneğinde yapılan değişiklikleri satıcıya bildirin.
    2. Satıcıdan güncellenmiş ödeme ayrıntılarını (örneğin, seçilen kargo seçeneğinin maliyetine göre ayarlanmış toplam tutar) alma.

Desteklenen yetki devretme işlemlerini bildirme

Tarayıcının, ödeme uygulamanızın sağlayabileceği ek bilgilerin listesini bilmesi gerekir. Böylece bu bilgilerin toplanmasını uygulamanıza devredebilir. Desteklenen delegasyonları uygulamanızın AndroidManifest.xml dosyasında <meta-data> olarak bildirin.

<activity
  android:name=".PaymentActivity"
    <meta-data
    android:name="org.chromium.payment_supported_delegations"
    android:resource="@array/chromium_payment_supported_delegations" />
</activity>

android:resource, aşağıdaki değerlerin tamamını veya bir alt kümesini içeren bir <string-array> öğesini işaret etmelidir:

  • payerName
  • payerEmail
  • payerPhone
  • shippingAddress

Aşağıdaki örnekte yalnızca kargo adresi ve ödeme yapan kullanıcının e-posta adresi sağlanabilir.

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <string-array name="chromium_payment_supported_delegations">
    <item>payerEmail</item>
    <item>shippingAddress</item>
  </string-array>
</resources>

Gerekli ödeme seçenekleri için PAY amaç ekstralarını ayrıştırın.

Satıcı, paymentOptions sözlüğünü kullanarak gerekli ek bilgileri belirtebilir. Chrome, paymentOptions Intent ekstraları PAY etkinliğine ileterek uygulamanızın sağlayabileceği gerekli seçeneklerin listesini sunar.

paymentOptions

paymentOptions, uygulamanızın yetkilendirme desteği bildirdiği, satıcı tarafından belirtilen ödeme seçeneklerinin alt kümesidir.

Kotlin

val paymentOptions: Bundle? = extras.getBundle("paymentOptions")
val requestPayerName: Boolean? = paymentOptions?.getBoolean("requestPayerName")
val requestPayerPhone: Boolean? = paymentOptions?.getBoolean("requestPayerPhone")
val requestPayerEmail: Boolean? = paymentOptions?.getBoolean("requestPayerEmail")
val requestShipping: Boolean? = paymentOptions?.getBoolean("requestShipping")
val shippingType: String? = paymentOptions?.getString("shippingType")

Java

Bundle paymentOptions = extras.getBundle("paymentOptions");
if (paymentOptions != null) {
    Boolean requestPayerName = paymentOptions.getBoolean("requestPayerName");
    Boolean requestPayerPhone = paymentOptions.getBoolean("requestPayerPhone");
    Boolean requestPayerEmail = paymentOptions.getBoolean("requestPayerEmail");
    Boolean requestShipping = paymentOptions.getBoolean("requestShipping");
    String shippingType = paymentOptions.getString("shippingType");
}

Aşağıdaki parametreleri içerebilir:

  • requestPayerName - Ödemeyi yapanın adının gerekli olup olmadığını belirten boole değeri.
  • requestPayerPhone: Ödeme yapan kullanıcının telefonunun gerekli olup olmadığını belirten boole değeri.
  • requestPayerEmail: Ödeme yapan kişinin e-posta adresinin gerekli olup olmadığını belirten boole değeri.
  • requestShipping - Kargo bilgilerinin gerekli olup olmadığını belirten boole değeri.
  • shippingType: Kargo türünü gösteren dize. Kargo türü "shipping", "delivery" veya "pickup" olabilir. Uygulamanız, kullanıcının adresini veya kargo seçeneklerini isterken kullanıcı arayüzünde bu ipucunu kullanabilir.

shippingOptions

shippingOptions, satıcı tarafından belirtilen kargo seçeneklerinin paketlenebilir dizisidir. Bu parametre yalnızca paymentOptions.requestShipping == true olduğunda bulunur.

Kotlin

val shippingOptions: List<ShippingOption>? =
    extras.getParcelableArray("shippingOptions")?.mapNotNull {
        p -> from(p as Bundle)
    }

Java

Parcelable[] shippingOptions = extras.getParcelableArray("shippingOptions");
for (Parcelable it : shippingOptions) {
  if (it != null && it instanceof Bundle) {
    Bundle shippingOption = (Bundle) it;
  }
}

Her kargo seçeneği, aşağıdaki anahtarlara sahip bir Bundle'dır.

  • id: Kargo seçeneği tanımlayıcısı.
  • label: Kullanıcıya gösterilen kargo seçeneği etiketi.
  • amount - Dize değerlerine sahip currency ve value anahtarlarını içeren kargo maliyeti paketi.
    • currency, kargo maliyetinin para birimini ISO4217 biçiminde, iyi biçimlendirilmiş 3 harfli alfabetik kod olarak gösterir.
    • value, kargo maliyetinin değerini geçerli bir ondalık para değeri olarak gösterir.
  • selected - Ödeme uygulaması kargo seçeneklerini gösterdiğinde kargo seçeneğinin seçilip seçilmeyeceği.

selected dışındaki tüm anahtarların dize değerleri vardır. selected, boole değerine sahip.

Kotlin

val id: String = bundle.getString("id")
val label: String = bundle.getString("label")
val amount: Bundle = bundle.getBundle("amount")
val selected: Boolean = bundle.getBoolean("selected", false)

Java

String id = bundle.getString("id");
String label = bundle.getString("label");
Bundle amount = bundle.getBundle("amount");
Boolean selected = bundle.getBoolean("selected", false);

Ödeme yanıtında gerekli bilgileri sağlama

Uygulamanız, PAY etkinliğine verdiği yanıtta gerekli ek bilgileri içermelidir.

Bunu yapmak için aşağıdaki parametreler Intent ekstraları olarak belirtilmelidir:

  • payerName - Ödemeyi yapanın tam adı. paymentOptions.requestPayerName doğru olduğunda bu, boş olmayan bir dize olmalıdır.
  • payerPhone: Ödeme yapanın telefon numarası. paymentOptions.requestPayerPhone doğru olduğunda bu, boş olmayan bir dize olmalıdır.
  • payerEmail: Ödeme yapanın e-posta adresi. paymentOptions.requestPayerEmail doğru olduğunda bu değer boş olmayan bir dize olmalıdır.
  • shippingAddress - Kullanıcının sağladığı kargo adresi. paymentOptions.requestShipping doğruysa bu boş olmayan bir paket olmalıdır. Pakette, fiziksel adresteki farklı bölümleri temsil eden aşağıdaki anahtarlar bulunmalıdır.
    • countryCode
    • postalCode
    • sortingCode
    • region
    • city
    • dependentLocality
    • addressLine
    • organization
    • recipient
    • phone addressLine dışındaki tüm anahtarların dize değerleri vardır. addressLine bir dize dizisidir.
  • shippingOptionId: Kullanıcı tarafından seçilen kargo seçeneğinin tanımlayıcısı. paymentOptions.requestShipping doğru olduğunda bu değer boş olmayan bir dize olmalıdır.

Ödeme yanıtını doğrulama

Çağrılan ödeme uygulamasından alınan bir ödeme yanıtının etkinlik sonucu RESULT_OK olarak ayarlanırsa Chrome, ekstralarında gerekli ek bilgileri kontrol eder. Doğrulama başarısız olursa Chrome, request.show() öğesinden reddedilen bir söz döndürür. Bu sözde, geliştiriciye yönelik aşağıdaki hata mesajlarından biri yer alır:

'Payment app returned invalid response. Missing field "payerEmail".'
'Payment app returned invalid response. Missing field "payerName".'
'Payment app returned invalid response. Missing field "payerPhone".'
'Payment app returned invalid shipping address in response.'
'... is not a valid CLDR country code, should be 2 upper case letters [A-Z].'
'Payment app returned invalid response. Missing field "shipping option".'

Aşağıdaki kod örneği, geçerli bir yanıt örneğidir:

Kotlin

fun Intent.populateRequestedPaymentOptions() {
    if (requestPayerName) {
        putExtra("payerName", "John Smith")
    }
    if (requestPayerPhone) {
        putExtra("payerPhone", "5555555555")
    }
    if (requestPayerEmail) {
        putExtra("payerEmail", "john.smith@gmail.com")
    }
    if (requestShipping) {
        val address: Bundle = Bundle()
        address.putString("countryCode", "CA")
        val addressLines: Array<String> =
                arrayOf<String>("111 Richmond st. West")
        address.putStringArray("addressLines", addressLines)
        address.putString("region", "Ontario")
        address.putString("city", "Toronto")
        address.putString("postalCode", "M5H2G4")
        address.putString("recipient", "John Smith")
        address.putString("phone", "5555555555")
        putExtra("shippingAddress", address)
        putExtra("shippingOptionId", "standard")
    }
}

Java

private Intent populateRequestedPaymentOptions() {
    Intent result = new Intent();
    if (requestPayerName) {
        result.putExtra("payerName", "John Smith");
    }
    if (requestPayerPhone) {
        presult.utExtra("payerPhone", "5555555555");
    }
    if (requestPayerEmail) {
        result.putExtra("payerEmail", "john.smith@gmail.com");
    }
    if (requestShipping) {
        Bundle address = new Bundle();
        address.putExtra("countryCode", "CA");
        address.putExtra("postalCode", "M5H2G4");
        address.putExtra("region", "Ontario");
        address.putExtra("city", "Toronto");
        String[] addressLines = new String[] {"111 Richmond st. West"};
        address.putExtra("addressLines", addressLines);
        address.putExtra("recipient", "John Smith");
        address.putExtra("phone", "5555555555");
        result.putExtra("shippingAddress", address);
        result.putExtra("shippingOptionId", "standard");
    }
    return result;
}

İsteğe bağlı: Dinamik akışı destekleme

Bazen bir işlemin toplam maliyeti artar. Örneğin, kullanıcı ekspres kargo seçeneğini belirlediğinde veya kullanıcı uluslararası bir kargo adresi seçtiğinde kullanılabilir kargo seçeneklerinin listesi ya da fiyatları değiştiğinde bu durum yaşanır. Uygulamanız, kullanıcının seçtiği kargo adresini veya seçeneğini sağladığında satıcıyı kargo adresi veya seçeneği değişiklikleri konusunda bilgilendirebilmeli ve kullanıcıya güncellenmiş ödeme ayrıntılarını (satıcı tarafından sağlanır) gösterebilmelidir.

Yeni değişiklikler hakkında satıcıyı bilgilendirmek için IPaymentDetailsUpdateServiceCallback arayüzünü uygulayın ve UPDATE_PAYMENT_DETAILS amaç filtresiyle AndroidManifest.xml içinde beyan edin.

Chrome, PAY amacını çağırdıktan hemen sonra PAY amaciyle aynı paketteki UPDATE_PAYMENT_DETAILS hizmetine (varsa) bağlanır ve setPaymentDetailsUpdateService(service) işlevini çağırarak ödeme uygulamanıza, kullanıcının ödeme yönteminde, kargo seçeneğinde veya kargo adresinde yapılan değişiklikleri bildirmek için IPaymentDetailsUpdateService uç noktasını sağlar.

packageManager.getPackagesForUid(Binder.getCallingUid()) amacını çağıran uygulamanın, PAY yöntemlerini çağıran uygulamayla aynı paket adına sahip olduğunu doğrulamak için süreçler arası iletişim (IPC) alırken packageManager.getPackagesForUid(Binder.getCallingUid()) kullanın.IPaymentDetailsUpdateServiceCallback

AIDL

Aşağıdaki içeriğe sahip iki AIDL dosyası oluşturun:

org/chromium/components/payments/IPaymentDetailsUpdateServiceCallback.aidl

package org.chromium.components.payments;

import android.os.Bundle;
import org.chromium.components.payments.IPaymentDetailsUpdateService;

interface IPaymentDetailsUpdateServiceCallback {
    oneway void updateWith(in Bundle updatedPaymentDetails);

    oneway void paymentDetailsNotUpdated();

    oneway void setPaymentDetailsUpdateService(IPaymentDetailsUpdateService service);
}

org/chromium/components/payments/IPaymentDetailsUpdateService.aidl

package org.chromium.components.payments;

import android.os.Bundle;
import org.chromium.components.payments.IPaymentDetailsUpdateServiceCallback;

interface IPaymentDetailsUpdateService {
    oneway void changePaymentMethod(in Bundle paymentHandlerMethodData,
            IPaymentDetailsUpdateServiceCallback callback);

    oneway void changeShippingOption(in String shippingOptionId,
            IPaymentDetailsUpdateServiceCallback callback);

    oneway void changeShippingAddress(in Bundle shippingAddress,
            IPaymentDetailsUpdateServiceCallback callback);
}

Hizmet

IPaymentDetailsUpdateServiceCallback hizmetini uygulayın.

Kotlin

class SampleUpdatePaymentDetailsCallbackService : Service() {
    private val binder = object : IPaymentDetailsUpdateServiceCallback.Stub() {
        override fun updateWith(updatedPaymentDetails: Bundle) {}

        override fun paymentDetailsNotUpdated() {}

        override fun setPaymentDetailsUpdateService(service: IPaymentDetailsUpdateService) {}
    }

    override fun onBind(intent: Intent?): IBinder? {
        return binder
    }
}

Java

import org.chromium.components.paymsnts.IPaymentDetailsUpdateServiceCallback;

public class SampleUpdatePaymentDetailsCallbackService extends Service {
    private final IPaymentDetailsUpdateServiceCallback.Stub mBinder =
        new IPaymentDetailsUpdateServiceCallback.Stub() {
            @Override
            public void updateWith(Bundle updatedPaymentDetails) {}

            @Override
            public void paymentDetailsNotUpdated() {}

            @Override
            public void setPaymentDetailsUpdateService(IPaymentDetailsUpdateService service) {}
        };

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }
}

AndroidManifest.xml

IPaymentDetailsUpdateServiceCallback için hizmeti AndroidManifest.xml dosyanızda kullanıma sunun.

<service
    android:name=".SampleUpdatePaymentDetailsCallbackService"
    android:exported="true">
    <intent-filter>
        <action android:name="org.chromium.intent.action.UPDATE_PAYMENT_DETAILS" />
    </intent-filter>
</service>

Kullanıcının seçtiği ödeme yöntemi, kargo adresi veya kargo seçeneğindeki değişiklikleri satıcıya bildirme

Kotlin

try {
    if (isOptionChange) {
        service?.changeShippingOption(selectedOptionId, callback)
    } else (isAddressChange) {
        service?.changeShippingAddress(selectedAddress, callback)
    } else {
        service?.changePaymentMethod(methodData, callback)
    }
} catch (e: RemoteException) {
    // Handle the remote exception
}

Java

if (service == null) {
  return;
}

try {
    if (isOptionChange) {
        service.changeShippingOption(selectedOptionId, callback);
    } else (isAddressChange) {
        service.changeShippingAddress(selectedAddress, callback);
    } else {
        service.changePaymentMethod(methodData, callback);
    }
} catch (RemoteException e) {
    // Handle the remote exception
}

changePaymentMethod

Kullanıcının seçtiği ödeme yöntemindeki değişiklikler hakkında satıcıyı bilgilendirir. paymentHandlerMethodData paketi, hem methodName hem de isteğe bağlı details anahtarlarını içerir. Her ikisi de dize değerlerine sahiptir. Chrome, boş olmayan bir methodName içeren boş olmayan bir paket olup olmadığını kontrol eder ve doğrulama başarısız olursa callback.updateWith kullanarak aşağıdaki hata mesajlarından birini içeren bir updatePaymentDetails gönderir.

'Method data required.'
'Method name required.'

changeShippingOption

Kullanıcının seçtiği kargo seçeneğindeki değişiklikler hakkında satıcıyı bilgilendirir. shippingOptionId, satıcı tarafından belirtilen kargo seçeneklerinden birinin tanımlayıcısı olmalıdır. Chrome, boş olmayan bir shippingOptionId olup olmadığını kontrol eder ve doğrulama başarısız olursa callback.updateWith kullanarak aşağıdaki hata mesajıyla birlikte bir updatePaymentDetails gönderir.

'Shipping option identifier required.'

changeShippingAddress

Kullanıcı tarafından sağlanan kargo adresindeki değişiklikler hakkında satıcıyı bilgilendirir. Chrome, geçerli bir countryCode ile boş olmayan bir shippingAddress paketi olup olmadığını kontrol eder ve doğrulama başarısız olursa callback.updateWith kullanarak aşağıdaki hata mesajıyla bir updatePaymentDetails gönderir.

'Payment app returned invalid shipping address in response.'

Geçersiz durum hata mesajı

Chrome, değişiklik isteklerinden herhangi birini alırken geçersiz bir durumla karşılaşırsa callback.updateWith paketini kısaltılmış bir updatePaymentDetails ile çağırır. Pakette yalnızca "Invalid state" ile error anahtarı bulunur. Geçersiz duruma örnekler:

  • Chrome, satıcının önceki bir değişikliğe (ör. devam eden bir değişiklik etkinliği) verdiği yanıtı bekliyorsa.
  • Ödeme uygulaması tarafından sağlanan kargo seçeneği tanımlayıcısı, satıcı tarafından belirtilen kargo seçeneklerinden hiçbirine ait değil.

Satıcıdan güncellenmiş ödeme ayrıntılarını alma

Kotlin

override fun updateWith(updatedPaymentDetails: Bundle) {}

override fun paymentDetailsNotUpdated() {}

Java

@Override
public void updateWith(Bundle updatedPaymentDetails) {}

@Override
public void paymentDetailsNotUpdated() {}

updatedPaymentDetails, PaymentRequestDetailsUpdate WebIDL sözlüğüne eşdeğer olan pakettir ve aşağıdaki isteğe bağlı anahtarları içerir:

  • total: Hem currency hem de value anahtarlarını içeren bir paket. Her iki anahtar da dize değerlerine sahiptir.
  • shippingOptions: Kargo seçenekleri için paketlenebilir dizi.
  • error - Genel bir hata mesajı içeren dize (ör. changeShippingOption geçerli bir kargo seçeneği tanımlayıcısı sağlamadığında)
  • stringifiedPaymentMethodErrors - Ödeme yöntemiyle ilgili doğrulama hatalarını gösteren bir JSON dizesi
  • addressErrors - shipping address ve string values ile aynı olan isteğe bağlı anahtarlar içeren bir paket. Her anahtar, kargo adresinin ilgili bölümüyle ilgili bir doğrulama hatasını temsil eder.
  • modifiers: Her biri total ve methodData alanına sahip, aynı zamanda Bundle olan bir Bundle dizisi.

Olmayan bir anahtar, değerinin değişmediği anlamına gelir.