pluspay_a2a
POS+ (Pluspay) Android uygulaması ile App-to-App (A2A) iletişim kurmak için geliştirilmiş Flutter eklentisi. Bu paket, Flutter uygulamanızdan POS+ uygulamasını başlatarak ödeme, iptal, EFT işlemleri, sipariş ödemeleri, gün sonu raporları ve parametre güncellemeleri yapmanızı sağlar.
Not: Bu paket yalnızca Android platformunu desteklemektedir. iOS desteği bulunmamaktadır.
Kurulum
Aşağıdaki komutu çalıştırın:
flutter pub add pluspay_a2a
Veya pubspec.yaml dosyanıza elle ekleyip flutter pub get çalıştırın:
dependencies:
pluspay_a2a: ^0.8.0
Not: Mevcut versiyonları pub.dev/packages/pluspay_a2a sayfasından görebilirsiniz.
Hızlı Başlangıç
import 'package:pluspay_a2a/pluspay_a2a.dart';
// 1. İstemciyi oluşturun ve başlatın
final pluspay = PPA2AClient();
await pluspay.initialize();
// 2. Ödeme başlatın
try {
final result = await pluspay.startPayment(
PPStartPaymentRequestModel.toRequest(
orderCode: 'ORD-001',
totalAmount: 150.0,
paymentType: PPPaymentType.POS,
paymentMethod: PPPaymentMethod.CC,
),
);
print('Ödeme başarılı: ${result.id}');
} on PPA2AException catch (e) {
print('Ödeme başarısız: ${e.errorCode} - ${e.message}');
}
// 3. İşiniz bittiğinde kaynakları temizleyin
await pluspay.dispose();
Dil (Locale)
POS+, isteğin header'ındaki locale alanına göre arayüzünü işlem süresince o dile çevirir ve cevap döndükten sonra cihazın önceki diline geri döner.
// Tüm istekler için varsayılan dil
await pluspay.initialize(locale: 'en');
// veya daha sonra
pluspay.locale = 'de';
// Tek bir istek için override
PPStartPaymentRequestModel.toRequest(
orderCode: 'ORD-001',
totalAmount: 150.0,
paymentType: PPPaymentType.POS,
paymentMethod: PPPaymentMethod.CC,
locale: 'ar',
);
- Desteklenen diller
ppSupportedLocalessabitinde listelenir:tr,en,ar,de,fr,it,es,ru,zh. en,en_USveen-USbiçimlerinin hepsi kabul edilir.- Alan gönderilmezse ya da desteklenmeyen bir dil gönderilirse POS+ mevcut dilinde açılır; hata dönmez.
- Kiosk cihazlarında bu alan yok sayılır.
- İsteğe ait
locale, istemcininlocaledeğerinden önceliklidir. error_messagemetinleri seçilen dilden bağımsız olarak her zaman Türkçedir (bkz. Hata Yönetimi).
İstemci Metodları
Tüm metodlar PPA2AClient sınıfı üzerindedir. Her metod başarılı durumda tipli bir response modeli döner, hata durumunda PPA2AException fırlatır.
| Metod | İstek Modeli | Yanıt Modeli | Açıklama |
|---|---|---|---|
startPayment |
PPStartPaymentRequestModel |
PPStartPaymentResponseModel |
Ödeme başlat |
cancelPayment |
PPCancelPaymentRequestModel |
PPStartPaymentResponseModel |
Ödeme iptal et |
startEftPayment |
PPEftPaymentRequestModel |
PPStartPaymentResponseModel |
EFT POS ödemesi başlat |
cancelEftPayment |
PPEftCancelRequestModel |
PPStartPaymentResponseModel |
EFT POS ödemesini iptal et |
startOrderPayment |
PPOrderPaymentRequestModel |
PPOrderPaymentResponseModel |
Sipariş ödemesi başlat |
startMultiPayment |
PPMultiPaymentRequest |
PPMultiPaymentResponseModel |
Çoklu ödeme başlat |
createOrder |
PPOrderCreateRequest |
PPOrderCreateResponseModel |
Ödeme başlatmadan sipariş oluştur |
triggerEod |
PPEodRequestModel |
PPEodResponseModel |
Gün sonu tetikle |
triggerParameters |
PPParameterRequestModel |
PPParametersResponseModel |
Parametre güncellemesi tetikle |
getAvailablePaymentMethods |
PPAvailablePaymentMethodsRequestModel |
PPAvailablePaymentMethodsResponseModel |
Aktif/kullanılabilir ödeme yöntemlerini sorgula |
getTransactionResult |
PPTransactionResultRequestModel |
PPStartPaymentResponseModel |
Tek bir işlemin sonucunu sorgula |
getOrderResult |
PPOrderResultRequestModel |
PPOrderPaymentResponseModel |
Siparişi ve tüm işlemlerini sorgula |
technicalCancel |
PPTechnicalCancelRequestModel |
PPTechnicalCancelResponseModel |
İşlemi teknik olarak iptal et |
Aynı anda tek istek: POS+ aynı anda yalnızca bir isteği işler. Bir isteğin cevabı beklenirken yeni bir istek gönderilirse, istemci intent atmadan hemen
PP_A2A_015(PPA2AErrorCodes.requestInProgress) fırlatır; bekleyen istek etkilenmez. 20 dakikadan uzun süredir cevapsız kalan bir istek kaybolmuş sayılır ve yeni isteği engellemez.
İstek Modelleri
Her istek modeli, düz ve kullanışlı bir API sunan toRequest factory constructor'ına sahiptir. İlgili alanları doğrudan geçirirsiniz; model dahili header + data yapısını sizin için oluşturur.
Ödeme Başlat
PPStartPaymentRequestModel.toRequest(
orderCode: 'ORD-001',
totalAmount: 100.0,
paymentType: PPPaymentType.POS,
paymentMethod: PPPaymentMethod.CC,
installment: 3, // opsiyonel
isPartial: false, // opsiyonel, varsayılan: false
partialType: null, // opsiyonel
products: [], // opsiyonel
billingInformation: null, // opsiyonel
);
Ödeme İptal
PPCancelPaymentRequestModel.toRequest(
orderCode: 'ORD-001',
transactionId: 'TX-123',
note: 'Müşteri iptali talep etti', // opsiyonel
);
EFT Ödeme
PPEftPaymentRequestModel.toRequest(
totalAmount: 250.0,
paymentType: PPPaymentType.POS,
paymentMethod: PPPaymentMethod.CC,
transactionId: 'EFT-001',
taxRate: 18,
installment: null, // opsiyonel
);
EFT İptal
PPEftCancelRequestModel.toRequest(
transactionId: 'EFT-001',
totalAmount: 250.0,
);
Sipariş Ödemesi
PPOrderPaymentRequestModel.toRequest(
orderCode: 'ORD-001',
);
Gün Sonu (EOD)
PPEodRequestModel.toRequest(
isAll: false,
types: [PPEodType.POS, PPEodType.MULTINET],
);
Parametre Yükleme
PPParameterRequestModel.toRequest(
isAll: true,
types: null,
);
Mevcut Ödeme Yöntemleri
POS+ üzerinde o an aktif/kullanılabilir ödeme tiplerini ve yöntemlerini sorgular. Ekstra parametre gerektirmez.
PPAvailablePaymentMethodsRequestModel.toRequest();
Sipariş Oluşturma (Order Create)
Ödeme başlatmadan yalnızca sipariş oluşturur. Oluşturulan sipariş daha sonra aynı orderCode ile startOrderPayment üzerinden tahsil edilebilir. orderCode POS+ üzerinde zaten kayıtlıysa sipariş güncellenir.
PPOrderCreateRequest.toRequest(
orderCode: 'ORD-001',
orderDate: DateTime.now(),
products: [
ProductModel(
id: 1,
sku: 'SKU-001',
title: 'Ürün 1',
price: 100.0,
quantity: 1,
taxRate: 10,
unit: PPQtyEnums.ADET,
vatInclude: true,
productType: PPProductTypeEnum.PHYSICALLY,
discountValue: 0,
),
],
currency: PPCurrencyType.TRY, // opsiyonel, varsayılan: TRY
deliveryType: PPDeliveryTypeEnum.CASH_ORDER, // opsiyonel, varsayılan: CASH_ORDER
discountAmount: 0, // opsiyonel, varsayılan: 0
billingInformation: null, // opsiyonel
installment: null, // opsiyonel
groupCode: null, // opsiyonel
note: null, // opsiyonel
);
Yanıt PPOrderCreateResponseModel (PPMultiPaymentResponseModel ile aynı sipariş detayı yapısı) döner.
Çoklu Ödeme (Multi Payment)
PPMultiPaymentRequest.toRequest(
orderCode: 'ORD-001',
orderDate: DateTime.now(),
changePaymentStatus: true,
products: [
ProductModel(
id: 1,
sku: 'SKU-001',
title: 'Ürün 1',
price: 100.0,
quantity: 1,
taxRate: 10,
unit: PPQtyEnums.ADET,
vatInclude: true,
productType: PPProductTypeEnum.PHYSICALLY,
discountValue: 0,
otvOrani: 0, // opsiyonel, varsayılan: 0
konaklamaOrani: 0, // opsiyonel, varsayılan: 0
),
],
transactions: [
TransactionModel(
paymentType: PPPaymentType.POS,
totalAmount: 100.0,
paymentMethod: PPPaymentMethod.CC,
),
],
currency: PPCurrencyType.TRY, // opsiyonel, varsayılan: TRY
deliveryType: PPDeliveryTypeEnum.CASH_ORDER, // opsiyonel, varsayılan: CASH_ORDER
discountAmount: 0, // opsiyonel, varsayılan: 0
billingInformation: null, // opsiyonel
installment: null, // opsiyonel
groupCode: null, // opsiyonel
note: null, // opsiyonel
canTryAgain: true, // opsiyonel, varsayılan: true
);
İşlem Sonucu Sorgulama (Transaction Result)
Tek bir işlemin güncel durumunu sorgular; ödeme başlatmaz. Zaman aşımı (PP_A2A_014) veya beklenmeyen hata (PP_A2A_007) sonrası işlemin gerçekten tamamlanıp tamamlanmadığını öğrenmek için kullanın. İşlem siparişte bulunamazsa PP_A2A_016 döner.
final tx = await pluspay.getTransactionResult(
PPTransactionResultRequestModel.toRequest(
orderCode: 'ORD-001',
transactionId: 'TX-001',
),
);
print(tx.status); // örn. "SUCCESS"
Sipariş Sonucu Sorgulama (Order Result)
Siparişi ve üzerindeki tüm işlemleri (web, link vb. kanallardan yapılanlar dahil) döner; ödeme başlatmaz. Her results[] öğesinde completed, işlem başarılıysa true olur.
final order = await pluspay.getOrderResult(
PPOrderResultRequestModel.toRequest(orderCode: 'ORD-001'),
);
print('${order.status} — kalan: ${order.amountDue}');
Teknik İptal (Technical Cancel)
Sonucu belirsiz kalan veya tutarsız bir işlemi teknik olarak iptal eder. Başarısız olursa PP_A2A_012 döner.
Cihaz desteği: Teknik iptal yalnızca PAX ve Kozen cihazlarda desteklenir. Diğer cihazlarda (Sunmi, SoftPOS, Kiosk vb.) istek
PP_A2A_012ile döner.
await pluspay.technicalCancel(
PPTechnicalCancelRequestModel.toRequest(
orderCode: 'ORD-001',
transactionId: 'TX-001',
),
);
Yanıt Modelleri
Bilinmeyen enum değerleri: POS+ bu paket sürümünün tanımadığı bir enum değeri döndürürse yanıt hata vermez; ilgili alan
UNKNOWNolur (PPParameterTypesiçinunknown). Zorunlu enum alanları hiç gelmezse deUNKNOWNolur; nullable alanlardanull, alanın gönderilmediği anlamına gelir. Liste alanlarında (örn.methods) bilinmeyen değerler atlanır.UNKNOWNyalnızca yanıtlarda görülür, isteklerde kullanmayın.
PPStartPaymentResponseModel
startPayment, cancelPayment, startEftPayment, cancelEftPayment ve getTransactionResult metodları tarafından döndürülür.
| Alan | Tip | Açıklama |
|---|---|---|
id |
String |
İşlem ID |
orderCode |
String |
Sipariş kodu |
paymentType |
PPPaymentType? |
Kullanılan ödeme tipi |
paymentMethod |
PPPaymentMethod? |
Kullanılan ödeme yöntemi |
totalAmount |
double |
Toplam tutar |
totalPaid |
double? |
Ödenen tutar |
amountDue |
double? |
Kalan tutar |
isPartial |
bool |
Parçalı ödeme olup olmadığı |
partialType |
PPPartialPaymentType? |
Parçalı ödeme tipi |
source |
String? |
Kaynak bilgisi |
status |
String? |
Durum metni |
actionStatus |
bool? |
İşlem başarı durumu |
invoice |
PPInvoiceModel? |
Fatura detayları |
payment |
PPPaymentModel? |
Ödeme detayları (RRN, maskelenmiş kart, slip) |
delivery |
PPDeliveryModel? |
Teslimat detayları |
PPOrderPaymentResponseModel
startOrderPayment ve getOrderResult metodları tarafından döndürülür.
| Alan | Tip | Açıklama |
|---|---|---|
grandTotal |
double |
Genel toplam |
status |
PPOrderStatusEnum? |
Sipariş durumu |
orderCode |
String |
Sipariş kodu |
totalAmount |
double |
Toplam tutar |
totalPaid |
double |
Ödenen tutar |
amountDue |
double |
Kalan tutar |
results |
List<PPOrderTransactionResult> |
İşlem sonuçları |
PPEodResponseModel
triggerEod metodu tarafından döndürülür.
| Alan | Tip | Açıklama |
|---|---|---|
results |
List<PPEodResponseItem> |
Tip bazında gün sonu sonuçları |
Her PPEodResponseItem; eodType (PPEodType?), success (bool) ve opsiyonel errorMessage alanlarını içerir.
PPParametersResponseModel
triggerParameters metodu tarafından döndürülür.
| Alan | Tip | Açıklama |
|---|---|---|
results |
List<PPParameterResultModel> |
Parametre güncelleme sonuçları |
Her PPParameterResultModel; type (PPParameterTypes?), completed (bool) ve opsiyonel errorMessage alanlarını içerir.
PPAvailablePaymentMethodsResponseModel
getAvailablePaymentMethods metodu tarafından döndürülür. Liste, oturumun profil/cihaz filtrelerinden geçmiş hâliyle döner — yani "şu an gerçekten yapılabilecek" ödeme yöntemleridir.
| Alan | Tip | Açıklama |
|---|---|---|
paymentTypes |
List<PPPaymentTypeMethodsModel> |
Aktif ödeme tipleri |
Her PPPaymentTypeMethodsModel:
| Alan | Tip | Açıklama |
|---|---|---|
code |
PPPaymentType? |
Ödeme tipi |
methods |
List<PPPaymentMethod> |
O tip için kullanılabilir yöntemler |
title |
String? |
Görünen ad (opsiyonel) |
final res = await pluspay.getAvailablePaymentMethods(
PPAvailablePaymentMethodsRequestModel.toRequest(),
);
for (final type in res.paymentTypes) {
print('${type.code} -> ${type.methods}');
}
PPMultiPaymentResponseModel
startMultiPayment metodu tarafından döndürülür.
| Alan | Tip | Açıklama |
|---|---|---|
id |
String |
İşlem ID |
orderCode |
String |
Sipariş kodu |
products |
List<PPMultiPaymentProduct> |
Ürün detayları |
transactions |
List<PPMultiPaymentTransaction> |
İşlem detayları |
paymentType |
PPPaymentType? |
Ödeme tipi |
paymentMethod |
PPPaymentMethod? |
Ödeme yöntemi |
status |
PPOrderStatusEnum? |
Sipariş durumu |
totalAmount |
double |
Toplam tutar |
discountAmount |
double |
İndirim tutarı |
subTotal |
double |
Ara toplam |
taxAmount |
double |
Vergi tutarı |
grandTotal |
double |
Genel toplam |
totalPaid |
double |
Ödenen tutar |
amountDue |
double |
Kalan tutar |
preTotal |
PPMultiPaymentPreTotal |
Ön toplam bilgileri |
deliveryType |
PPDeliveryTypeEnum? |
Teslimat tipi |
customer |
PPMultiPaymentCustomer? |
Müşteri bilgileri |
PPTechnicalCancelResponseModel
technicalCancel metodu tarafından döndürülür.
| Alan | Tip | Açıklama |
|---|---|---|
orderCode |
String |
Sipariş kodu |
transactionId |
String |
İptal edilen işlem ID |
status |
String |
Başarılı durumda "SUCCESS" |
Enum'lar
PPPaymentType
POS+ tarafından desteklenen ödeme tipleri.
POS, PAYCELL, HEPSIPAY, ISTANBULCARD, CASH, ONLINE, BANK_TRANSFER, GASTROPAY, CIO_CARD, IWALLET, PAYE, MULTINET, METROPOL, FASTPAY, TICKET, EDENRED, SETCARD, SODEXO, GETIRPAY, TOKENFLEX, YEMEKMATIK, ON_CREDIT, VIRTUAL_POS, CUZDANPLUS, INSTALLMENT
PPPaymentMethod
POS+ tarafından desteklenen ödeme yöntemleri.
CC, CASH, QR, QR_R, NFC, QUICKCODE, MOBILE, SWIPE, NONE, ONLINE, TRENDYOL, GETIR, YEMEKSEPETI, MIGROSYEMEK, CHIP, LINK, NFC_R, PAYCELL_LINK, PAYCELL_MERCHANT_PAGE
PPEodType
Gün sonu rapor tipleri.
POS, CASH, BANK_TRANSFER, ONLINE, OTHER, MULTINET, SODEXO, SETCARD, TICKET, METROPOL, PAYE, TOKENFLEX, EDENRED, CUZDANPLUS, IWALLET
PPParameterTypes
Parametre güncelleme tipleri.
bank, multinet, metropol, paye, iwallet
PPPartialPaymentType
AMOUNT, PRODUCT
PPOrderStatusEnum
CANCEL, NOT_RESPONSE, WAITING, SUCCESS
PPDeliveryStatusEnum
WAITING, PREPREING, READY, ONWAY, COMPLETE, CANCEL
PPDeliveryTypeEnum
CASH_ORDER, PACKAGE_ORDER, TABLE_ORDER, TAKE_AWAY, TAKE_CLOSE
PPCurrencyType
TRY, USD, EUR, GBP
PPProductTypeEnum
PHYSICALLY, VIRTUAL, INFO, MD, DSN, QP, KFO, COMMISSION, HGS
PPQtyEnums
Miktar birimleri.
ADET, KG, GR, LT, MT, KOLI, PAKET, PORSIYON
PPDiscountTypeEnum
PERCENTAGE, FIXED_AMOUNT
PPDocumentTypeEnum
EFATURA, EARSIV, BILGIFISI
PPDocumentStatusEnum
SUCCESS, CANCEL, FAIL, WAITING, NONE
PPTransactionStatusEnum
SUCCESS, CANCEL, FAIL, NONE, WAITING, NOT_RESPONSE
PPTransactionTypeEnum
START, SATIS, CANCEL, REFUND, IADE
PPOrderSourceEnum
POS, WEB, TSM, KIOSK
Hata Yönetimi
POS+ bir hata yanıtı döndürdüğünde (örn. kullanıcı iptali, reddedilen ödeme), istemci PPA2AException fırlatır. Hata kodlarını PPA2AErrorCodes sabitleriyle karşılaştırın:
try {
final result = await pluspay.startPayment(request);
} on PPA2AException catch (e) {
switch (e.errorCode) {
case PPA2AErrorCodes.requestInProgress:
// önceki isteğin cevabını bekleyin
break;
case PPA2AErrorCodes.timeout:
case PPA2AErrorCodes.unexpectedException:
// işlemin durumunu getTransactionResult / getOrderResult ile sorgulayın
break;
default:
showError(myTextFor(e.errorCode));
}
}
messageher zaman Türkçedir. POS+'ın döndürdüğüerror_message, header'da gönderilenlocale'den bağımsızdır. Kullanıcıya göstereceğiniz metnierrorCodeüzerinden kendiniz üretin.
| Hata Kodu | Sabit | Açıklama |
|---|---|---|
PP_A2A_001 |
requestCannotBeNull |
İstek boş |
PP_A2A_002 |
dataCannotBeNull |
İşlem data gerektiriyor ama gönderilmedi |
PP_A2A_003 |
invalidClientToken |
Client token geçersiz |
PP_A2A_004 |
invalidEodRequest |
Geçersiz gün sonu isteği (is_all false iken types boş) |
PP_A2A_005 |
invalidParameterRequest |
Geçersiz parametre isteği (is_all false iken types boş) |
PP_A2A_006 |
invalidRequestParameter |
data içindeki bir alan eksik/geçersiz |
PP_A2A_007 |
unexpectedException |
POS+'ta beklenmeyen hata; işlemin durumunu sorgulayın |
PP_A2A_008 |
invalidRequestHeader |
header eksik/geçersiz |
PP_A2A_009 |
invalidTransactionType |
Bilinmeyen transaction_type |
PP_A2A_010 |
invalidFieldHeader |
İşlemin gerektirdiği header alanı (order_code, transaction_id) eksik/geçersiz |
PP_A2A_011 |
needsToLoginAtLeastOnce |
POS+ bu cihazda hiç giriş yapmamış |
PP_A2A_012 |
errorOnProcess |
İşlem POS+'ta başarısız oldu (detay mesajda) |
PP_A2A_013 |
autoLoginFailed |
POS+ otomatik giriş yapamadı |
PP_A2A_014 |
timeout |
Zaman aşımı (bkz. Zaman Aşımı) |
PP_A2A_015 |
requestInProgress |
Önceki bir istek hâlâ işleniyor |
PP_A2A_016 |
transactionNotFound |
TRANSACTION_RESULT: işlem siparişte bulunamadı |
LAUNCH_INTENT_ERROR |
launchIntentError |
İstemci: POS+ uygulaması başlatılamadı |
PP-A2A-PARSE |
parseError |
İstemci: yanıt JSON'ı ayrıştırılamadı |
Zaman Aşımı
- POS+ kapalıyken gelen bir istekte, uygulamanın açılıp isteği karşılayacak hâle gelmesi için 3 dakika beklenir.
- İşlemin kendisi için üst sınır 15 dakikadır.
- İki durumda da POS+
PP_A2A_014döner. - İstemci tarafında kendi zaman aşımınızı uyguluyorsanız bu süre 15 dakikadan uzun olmalıdır; aksi hâlde POS+'ta tamamlanmış bir ödeme sizin tarafınızda başarısız görünebilir.
PP_A2A_014veyaPP_A2A_007aldığınızda işlemin gerçek sonucunugetTransactionResult(TRANSACTION_RESULT) ya dagetOrderResult(ORDER_RESULT) ile sorgulayın.
Yaşam Döngüsü
class _MyPageState extends State<MyPage> {
final _pluspay = PPA2AClient();
@override
void initState() {
super.initState();
_pluspay.initialize();
}
@override
void dispose() {
_pluspay.dispose();
super.dispose();
}
}
initialize() diğer tüm metodlardan önce çağrılmalıdır. Uygulamanın paket bilgilerini alır ve POS+ sonuçları için bir broadcast receiver kaydeder. İstemciye artık ihtiyaç kalmadığında receiver'ı temizlemek için dispose() çağrılmalıdır.
Gereksinimler
- Yalnızca Android
- Cihazda POS+ uygulaması yüklü olmalıdır
- Minimum SDK: 24