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 standart 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ı bir ö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 işlemi, ö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. Kargo seçeneklerini ve toplam fiyatı nasıl dinamik olarak etkilediğini görün.

Zaten mevcut olan 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 PAY amaç ekstralarını ayrıştırı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ı (ör. seçilen kargo seçeneğinin maliyetine göre ayarlanmış toplam tutar) alma.

Desteklenen yetki devretme işlemlerini beyan etme

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 yetki devirlerini uygulamanızın AndroidManifest.xml dosyasında <meta-data> olarak tanımlayın.

<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 extras PAY etkinliğine ileterek uygulamanızın sağlayabileceği gerekli seçeneklerin listesini sunar.

paymentOptions

paymentOptions, uygulamanızın yetki devri 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: Ödeyenin 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ğeri içeriyor.

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.

Bunun 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: Ödemeyi yapanın e-posta adresi. paymentOptions.requestPayerEmail doğru olduğunda bu, boş olmayan bir dize olmalıdır.
  • shippingAddress - Kullanıcı tarafından sağlanan kargo adresi. Bu, paymentOptions.requestShipping doğru olduğunda 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 dizelerden oluşan bir dizidir.
  • shippingOptionId: Kullanıcı tarafından seçilen kargo seçeneğinin tanımlayıcısı. Bu, paymentOptions.requestShipping doğru olduğunda 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, geliştiriciye yönelik aşağıdaki hata mesajlarından biriyle request.show()'dan reddedilen bir söz döndürü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ıta dair örnektir:

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ış desteği

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 mevcut 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 ya da seçeneği değişiklikleri hakkında 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.

IPaymentDetailsUpdateServiceCallback yöntemlerini çağıran uygulamayla aynı paket adına sahip olup olmadığını doğrulamak için PAY amacını çağıran uygulamayı doğrulamak üzere packageManager.getPackagesForUid(Binder.getCallingUid()) yöntemini kullanın.

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 hizmetini AndroidManifest.xml içinde 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 bildirin.

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ı tarafından seçilen 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 aldığında geçersiz bir durumla karşılaşırsa callback.updateWith işlevini, düzeltilmiş bir updatePaymentDetails paketiyle çağırır. Paket yalnızca error anahtarını "Invalid state" ile birlikte içerir. Geçersiz duruma örnekler:

  • Chrome, önceki bir değişikliğe (ör. devam eden bir değişiklik etkinliği) ilişkin satıcının yanıtını beklerken.
  • Ö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 pakettir ve aşağıdaki isteğe bağlı anahtarları içerir:

  • total: currency ve 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ı temsil eden bir JSON dizesi
  • addressErrors - shipping address ve dize değerleriyle 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, paketlenebilir bir Paket dizisi. Bu alanlar da Paketlerdir.

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