BKM Express API Listesi
İş yeri olarak BKM Express API'lerini kullanarak aşağıdaki işlemleri gerçekleştirebilirsiniz;
İşlem Listesi Sorgulama: İş yerinizde BKM Express üzerinden yapılmış başarılı/başarısız işlemleri listeleyebilirsiniz.
Ön Otorizasyon Kapama: BKM Express üzerinden daha önce ön otorizasyonlu yaptığınız bir işlemin, ön otorizasyon kapamasını yapabilirsiniz.
Adres Entegrasyonu: BKM Express üzerinden kullanıcılarınızın adres bilgilerini alarak ödeme işlemini sağlayabilirsiniz.
İptal İade Servisi: BKM Express üzerinden gerçekleşen sanal pos işlemlerin İptal / İade sürecini sağlayan servistir.
BIN Servisi: İşyerinin E-Ticaret Bin Listesini alabileceği rest servistir.
Flow QR Servisi: BKM Express Flow 2.0 entgrasyonumuz üzerinden size dönülen ticket token id'yi QR'a çevirerek ödeme işlemi alabilirsiniz.
Ortamlar
BKM Express API'leri iki ortam üzerinde bulunur. Geliştirme yaparken test edebilmeniz için PREPROD
ortamını kullanabilirsiniz. Gerçek ortamda yapılan işlemler için PRODUCTION
ortamı kullanılmalıdır.
API'ler için dokümanda belirtilen endpoint adreslerine iki ortam üzerinden erişim sağlayabilirsiniz.
Genel Değişkenler
Değişken | Açıklama |
---|---|
MERCHANT-ID | BKM tarafından size verilen ID değerini belirtir |
PRIVATE-KEY | Imzalama işlemleri için tarafınızda üretilen şifreleme değerini belirtir. |
SIGNATURE | {MERCHANT-ID} verisi ile {PRIVATE-KEY} kullanılarak RSA-SHA256 algoritmasına göre yapılan imzalama işleminin sonucudur. |
TICKET-ID | BKM aracılığıyla yapılmış ödeme işlemi id bilgisini içerir. |
ORDER-ID | BKM aracılığıyla yapılmış ödeme'de oluşan sipariş numarasını belirtir. |
POS-USER-ID | RSA ile şifrelenmiş sanal pos kullanıcı id değerini belirtir. Kuş tüyü müşteriler için gerekli değildir. |
POS-PASSWORD | RSA ile şifrelenmiş sanal pos şifre değerini belirtir. Kuş tüyü müşteriler için gerekli değildir. |
POS-SERVICE-URL | Pos servis url bilgisini belirtir. Kuş tüyü müşteriler için gerekli değildir. |
POS-BANK-CODE | Sanal POS kullanılacak banka kodunu belirtir. Kuş tüyü müşteriler için gerekli değildir. |
POS-EXTRA | Pos bilgilerini belirtir. Kuş tüyü müşteriler için gerekli değildir. |
TOTAL-AMOUNT | Toplam tutar bilgisini belirtir. |
POS-TRANSACTION-ID | Ön otorizasyon kapama işlemi yapılacak tutar bilgisini belirtir. |
POS-RESPONSE | Pos sonucunu belirtir (“APPROVED” veya “FAILED”). |
POS-RAW-RESPONSE | Pos işleminde bankadan dönen ham sonucu belirtir. |
1. İşlem Listesi Sorgulama
Üye iş yerleri üzerinden BKM Express aracılığla yapılan işlemlerin sonuçlarını alabilmeniz için geliştirilmiştir. Başarılı/başarısız işlemleri belli bir tarih aralığında ya da ticketId veya orderId üzerinden tekil sorgulamanıza yardımcı olur.
İşlem Listesi Sorgulama API'si üzerinden tekil işlem sorgulama ve toplu işlem sorgulama yapılabilir.
İşlem Listesi Sorgulama API'sini kullanmak için BKM'den MerchantID'niz için yetki almalısınız. Bunun için isyerientegrasyon@bkm.com.tr ile iletişime geçebilirsiniz.
İş yerinin yapacağı istek
Yapılması gereken isteği yandaki kod bloğunda görebilirsiniz.
Aşağıda da istekteki alanların detaylarını görebilirsiniz.
// Örnek bir toplu işlem sorgulama curl isteği:
curl -X POST 'https://api.bkmexpress.com.tr/v1/merchant/merchantTransactionList'\
-H 'content-type: application/json' \
-d '{
"id":"YOUR-MERCHANT-ID",
"signature":"Signature",
"startDate": {TRANSACTION-START-DATE}, // "2017-04-02 01:00",
"endDate": {TRANSACTION-END-DATE}, // "2017-05-02 23:00",
"paymentResult": {PAYMENT-RESULT}, // "1"
"page":"",
"orderType":null
}'
// Örnek bir tek işlem sorgulama curl isteği:
curl -X POST 'https://api.bkmexpress.com.tr/v1/merchant/merchantTransactionList' \
-H 'content-type: application/json' \
-d '{
"id":"YOUR-MERCHANT-ID",
"signature":"Signature",
"ticketId": {TICKET-ID},
"orderId": {ORDER-ID},
}'
İstek | |
---|---|
Bağlantı Adresi | Prod: https://api.bkmexpress.com.tr/v1/merchant/merchantTransactionList |
Bağlantı Adresi | Preprod: https://preprod-api.bkmexpress.com.tr/v1/merchant/merchantTransactionList |
Bağlantı Metodu | POST |
İstek Content-Type Başlığı |
application/json |
İstek içeriği | Toplu işlem sorgulama örneği:{“id”:“Your-Merchant-ID”, “signature”:“Signature”, startDate":“2017-04-02 01:00”, “endDate”:“2017-05-02 23:00”, “paymentResult”:“1”, “page”:“”, “orderType”:null} Tek işlem sorgulama örneği:{“id”:“Your-Merchant-ID”, “signature”:“Signature”, ticketId: “TICKET_ID” or “orderId”: “ORDER_ID” |
İstek içerisindeki parametrelerin açıklamaları | |
---|---|
id alanı |
BKM tarafından size iletilen ‘id’ bilgisi |
signature alanı |
'id’ alanına yazılan değerin BKM tarafına public kısmını ilettiğiniz private key ile şifrelenmiş hali. “SHA-256 with RSA” şifreleme yöntemi ile şifrelenmeli. Örnek şifreleme kodu için tıklayın |
startDate alanı |
'yy-MM-dd HH:mm’ formatında iletilen işlem sorgu başlangıç tarih değeri. Tek işlem sorgulamada geçersiz olacaktır |
endDate alanı |
'yy-MM-dd HH:mm’ formatında iletilen işlem sorgu bitiş tarih değeri. Tek işlem sorgulamada geçersiz olacaktır. |
paymentResult alanı |
“0” ya da “1” olarak yollanır. 0:başarısız işlemler 1:başarılı işlemler. Tek işlem sorgulamada geçersiz olacaktır. |
page alanı |
“” ya da istenilen sayfa değeri yollanır. İşlem listesi ilk sorgusu size toplam satır sayısını döner. 50'şer olarak sayfalayarak sorgulama yapabilirsiniz. Tek işlem sorgulamada geçersiz olacaktır. |
orderType alanı |
true ya da false olarak yollanır ve tarihe göre sıralamayı seçmenize yarar. null ve false değerleri artan olarak sıralama yapar. Tek işlem sorgulamada geçersiz olacaktır. |
ticketId alanı |
Sorgulanmak istenen ödeme işlemine ait ticketId değeri yollanır. Toplu işlem sorgulamada geçersiz olacaktır. |
orderId alanı |
Sorgulanmak istenen ödeme işlemine ait daha önce BKM Express'e gönderilmiş sipariş numarası(orderId) değeri yollanır. Toplu işlem sorgulamada geçersiz olacaktır. |
BKM Express'ten iş yerine dönülecek cevap
BKM Express'ten size dönecek cevabı yandaki kod bloğunda görebilirsiniz.
Aşağıda da cevaptaki alanların detaylarını görebilirsiniz.
// Örnek bir başarılı toplu işlem sorgulama cevabı:
{
"code": "OK-COM-001",
"call": "merchant/{id}/command",
"description": "Başarıyla tamamlandı.",
"message": "Completed successfully.",
"result": "ok",
"parameters": {},
"data": {
"status": "ok",
"transactionCount": "179",
"page": "1",
"merchantTransactions": [
{
"ticket": "fac1ee27-6132-45d6-99c9-160f91e421a3",
"amount": "6000,52",
"paymentAmount": "6000,52",
"paymentDate": "2017-11-01 01:16:41.292",
"bankCode": "0010",
"vposBankCode": "0010",
"installment": "1",
"paymentResult": "0",
"posResponse": "{\"orderId\":\"\",\"groupId\":\"\",\"response\":\"Error\",\"authCode\":\"\",\"hostRefNum\":\"\",\"procReturnCode\":\"99\",\"transId\":\"15177OSDD00100673\",\"errMsg\":\"HP SV - 4200 TL üzeri işlem kabul edilmedi.\",\"extra\":{\"settleId\":\"\",\"trxDate\":\"20171101 01:17:26\",\"errorCode\":\"CORE-2507\",\"hostDate\":null,\"numCode\":\"992507\"}}",
"failResultReason": "Sanal POS'tan hata alındı.",
"failResultCode": "04",
"isPreAuth": "false",
"tcknHash": "d10a5af1bb4a62e47911002232b2229022137b4f6cbe9d7fbaa8db6976615f72",
"first6digits": "454360",
"last4digits": "3655"
},
...
]
}
}
// Örnek bir başarılı tek işlem sorgulama cevabı:
{
"code": "OK-COM-001",
"call": "merchant/merchantTransactionList",
"description": "Başarıyla tamamlandı.",
"message": "Completed successfully.",
"result": "ok",
"parameters": {},
"data": {
"status": "ok",
"merchantTransactions": [
{
"ticket": "7ea9305d-5855-418d-ab67-4f34dbfe4a01",
"orderId": "fdc212f1-4ee8-4789-b01a-e726b3ca5633",
"amount": "14,44",
"paymentAmount": "14,44",
"paymentDate": "2019-09-16 09:28:27.38",
"bankCode": "0010",
"vposBankCode": "0046",
"installment": "1",
"paymentResult": "1",
"authorizationCode": "662480",
"posResponse": "{\"orderId\":\"fdc212f1-4ee8-4789-b01a-e726b3ca5633\",\"groupId\":\"fdc212f1-4ee8-4789-b01a-e726b3ca5633\",\"response\":\"Approved\",\"authCode\":\"662480\",\"hostRefNum\":\"509614421347\",\"procReturnCode\":\"00\",\"transId\":\"15096OrKA00120108\",\"errMsg\":\"\",\"extra\":{\"settleId\":\"854\",\"trxDate\":\"20150406 14:43:09\",\"errorCode\":\"\",\"hostDate\":null,\"numCode\":\"00\",\"hostMsg\":\"000 ONAY KODU XXXXXX\",\"cevapAltKoduAciklama\":null,\"cevapAltKodu\":null}}",
"referenceNumber": "509614421347",
"failResultCode": "00",
"isPreAuth": "false",
"tcknHash": "59b1875e1f86ff80bdfa7bfbd65dab880e0ddb91dce45bd82da016a7a63dca4b",
"first6digits": "540130",
"last4digits": "4456"
}
]
}
}
Cevap İçeriği | |
---|---|
Content-Type Başlığı |
application/json |
result alanı |
Bu alan içerisinde istek sonucu döner. 'ok’ ise işlem başarılı olmuştur. |
code alanı |
Bu alan içerisinde istek sonuç kodu döner. İşlem listesi isteği hata kodları için tıklayın. |
data alanı |
Bu alan işlemleriniz ile ilgili bilgileri içerir. |
data İçeriği |
|
---|---|
transactionCount alanı |
Yapılan istekte dönen toplam işlem sayısını içerir. |
page alanı |
İstek yapılan sayfa numarasını içerir. |
merchantTransactions alanı |
İstek sonucunda dönen işlem özetlerini içerir. |
data .merchantTransactions İçeriği |
|
---|---|
orderId alanı |
İşlemin sipariş numarası bilgisini içerir. |
amount alanı |
İşlemin başında belirtilen tutar bilgisini içerir. |
paymentAmount alanı |
İşlemin sonunda pos'a yollanan tutar bilgisini içerir. Vade farklı işlemlerde amount alanından farklı olabilir. |
paymentDate alanı |
İşlemin zaman bilgisini içerir. |
bankCode alanı |
İşlemde kullanılan kartın banka bilgisini içerir. |
vposBankCode alanı |
İşlemde kullanılan vpos'un banka bilgisini içerir. |
installment alanı |
İşlemin taksit bilgisini içerir. |
paymentResult alanı |
İşlemin başarılı olup olmadığını gösterir. 1 başarılı, 0 başarısız. |
failResultReason alanı |
Başarısız işlemlerde işlemin neden başarısız olduğu bilgisini içerir. Başarılı işlemlerde bu alan boş dönülecektir. Alabileceği değerler; “Gönderilen parametrelere göre sistemde herhangi bir kayıt bulunamadı.”,“Kullanıcı ödeme işlemini tamamlamadı.”,“Sanal POS'tan hata alındı”, “OTP'de hata alındı” |
failResultCode alanı |
Hatalı işlem kodu. 00: Başarılı, 02: Kullanıcı ödeme işlemini tamamlamadı, 03: Otp'de hata alındı, 04: Sanal POS'tan hata alındı, 05: Kullanıcı işlemi iptal etti |
authorizationCode alanı |
İşlemin authorizationCode bilgisini içerir. |
posResponse alanı |
İşlemin vpos üzerinden aldığı cevap bilgilerini içerir. |
referenceNumber alanı |
İşlemin referenceNumber bilgisini içerir. |
isPreAuth alanı |
İşlemin ön otorizasyona ya da ödemeye ait olduğunu gösterir. Ödeme işlemi için bu değer “false”, ön otorizasyon için “true"dir. |
isPostAuth alanı |
İşlemin ön otorizasyon kapama işlemi olduğunu gösterir. Kapama işlemi gerçekleştiğinde true olarak döner. |
isReversed alanı |
Başarılı işlem sonrası ödeme BKMExpress üzerinden İptal/İade edilmiş ise true olarak döner. |
reversalAmount alanı |
İptal/İade tutarı |
tcknHash alanı |
Kullanıcıya ait tckn bilgisini hash değerinde döner. |
first6digits alanı |
İşleme ait kartın ilk 6 hane bin bilgisini döner. |
last4digits alanı |
İşleme ait kartın son 4 hane bin bilgisini döner. |
İşlem listesi sorgulama isteği hata kodlari
İşlem listesi isteğine dönen hata kodları
KOD | AÇIKLAMA |
---|---|
OK-FE-CON-001 | Başarıyla tamamlandı. |
EX-FE-CON-009 | id ya da signature parametresi eksik. |
EX-MS-MRC-002 | İş yeri id bilgisi yanlış. |
EX-MS-MRC-004 | İş yeri imzalama hatası. |
EX-COM-001 | İş yeri imzalama formatı hatalı. |
EX-COM-002 | Yapılan istekteki parametreler kontrol edilmeli. |
EX-COM-004 | Yapılan istekteki parametreler kontrol edilmeli. |
EX-FE-CON-004 | Bağlantı bilgilerinin kullanım süresi doldu. |
EX-MS-MRC-005 | İş yerinin işlem listesini çağırmaya yetkisi yok. |
EX-MS-MRC-006 | En fazla hata mesajında belirtilen ay kadar öncesine sorgulama yapılabilir. |
EX-MS-MRC-007 | Maksimum hata mesajında belirtilen gün sayısı kadar sorgulama yapılabilir. |
EX-MS-MRC-008 | Maksimum hata mesajında belirtilen sayfa sayısı kadar istek yapılabilir. |
EX-MER-COM-001 | Tarih formatı 'yyyy-MM-dd HH:mm’ olmalı. |
EX-MER-COM-002 | Başlangıç ve bitiş tarihi birbirinden farklı olmalı. |
EX-MER-COM-003 | Başlangıç ve bitiş tarihi şu an ki zamandan önce olmalı. |
EX-MER-COM-004 | Bitiş tarihi, başlangıç tarihinden sonra olmalı. |
EX-MER-COM-005 | orderId ve ticketId parametreleri birlikte kullanılamaz. |
EX-MER-COM-006 | orderId veya ticketId ile paymentResult parametresi kullanılamaz. |
EX-MER-COM-007 | orderId veya ticketId ile startDate parametresi kullanılamaz. |
EX-MER-COM-008 | orderId veya ticketId ile endDate parametresi kullanılamaz. |
EX-MER-COM-009 | orderId veya ticketId ile page parametresi kullanılamaz. |
EX-MER-COM-010 | orderId veya ticketId ile orderType parametresi kullanılamaz. |
EX-MER-COM-011 | İşlem listesi sorgulama için yeterli parametre yok. |
2. Ön Otorizasyon Kapama
BKM Express üzerinden daha önce ön otorizasyonlu yaptığınız bir işlemin, ön otorizasyon kapamasını yapabilirsiniz.
Önemli: BKM Ön provizyon kapama servisinde sadece işbankası ve garanti sanal pos desteklenmektedir.
İş yerinin yapacağı istek
Yapılması gereken isteği yandaki kod bloğunda görebilirsiniz.
Aşağıda da istekteki alanların detaylarını görebilirsiniz.
curl -X POST https://api.bkmexpress.com.tr/v1/merchant/postAuth\
-H 'content-type: application/json' \
-d '{
"id":"YOUR-MERCHANT-ID",
"signature":"Signature",
"ticketId": {TICKET-ID},
"orderId": {ORDER-ID}, //(optional)
"totalAmount": {TOTAL-AMOUNT},
"posUserId": {POS-USER-ID}, // (RSA şifreleme, Kuş tüyü olmayanlar için zorunlu)
"posPassword": {POS-PASSWORD},// (RSA şifreleme, Kuş tüyü olmayanlar için zorunlu)
"serviceUrl": {POS-SERVICE-URL}, // (RSA şifreleme, Kuş tüyü olmayanlar için zorunlu)
"vposBankCode": {POS-BANK-CODE}, // (Kuş tüyü olmayanlar için zorunlu),
"extra":{POS-EXTRA} // (seçimli)
}'
İstek | |
---|---|
Bağlantı Adresi | Prod: https://api.bkmexpress.com.tr/v1/merchant/postAuth |
Bağlantı Adresi | Preprod: https://preprod-api.bkmexpress.com.tr/v1/merchant/postAuth |
Bağlantı Metodu | POST |
Content-Type |
application/json |
İstek içeriği | { "id”: {Your-Merchant-ID}, “signature”: {SIGNATURE}, “ticketId”: {TICKET-ID}, “orderId”: {ORDER-ID}, “totalAmount”: {TOTAL-AMOUNT}, “posUserId”: {POS-USER-ID}, “posPassword”: {POS-PASSWORD}, “serviceUrl”: {POS-SERVICE-URL}, “bankIndicator”: {BANK-CODE}, “extra”:{POS-EXTRA} } |
İstek içerisindeki parametrelerin açıklamaları: | |
---|---|
id alanı |
BKM tarafından size iletilen 'id’ bilgisi |
signature alanı |
'id’ alanına yazılan değerin BKM tarafına public kısmını ilettiğiniz private key ile şifrelenmiş hali. “SHA-256 with RSA” şifreleme yöntemi ile şifrelenmeli. Örnek şifreleme kodu için tıklayın |
ticketId alanı |
Ödeme işlemine ait ticketId bilgisi |
orderId alanı |
Sipariş numara bilgisi |
totalAmount alanı |
Toplam tutar bilgisi |
posUserId alanı |
Pos kullanıcı bilgisi. “SHA-256 with RSA” şifreleme yöntemi ile şifrelenmeli. Şifrelenmiş sonuç Base64.encode edilmeli. |
posPassword alanı |
Pos şifre bilgisi. “SHA-256 with RSA” şifreleme yöntemi ile şifrelenmeli. Şifrelenmiş sonuç Base64.encode edilmeli. |
serviceUrl alanı |
Pos servis bağlantı bilgisi. “SHA-256 with RSA” şifreleme yöntemi ile şifrelenmeli. Şifrelenmiş sonuç Base64.encode edilmeli. |
vposBankCode alanı |
Pos Banka kodu bilgisi |
extra alanı |
Pos ek bilgiler. |
BKM Express'ten iş yerine dönülecek cevap
BKM Express'ten size dönecek cevabı yandaki kod bloğunda görebilirsiniz.
Aşağıda da cevaptaki alanların detaylarını görebilirsiniz.
// Otorizasyon kapama sonucunda aşağıdaki şekilde response döner.
{ headers: {
"content-type":"application/json"
}
response: {
"code": "OK-COM-001",
"call": "merchant/postAuth",
"description": "Başarıyla tamamlandı.",
"message": "Completed successfully",
"result": "ok",
"parameters": {},
"data": {
"bkmTokenId": {TICKET_ID},
"totalAmount": {TOTAL-AMOUNT},
"posResult": {
"posResponse": "APPROVED",
"posResultCode": "00",
"orderId": {ORDER-ID},
"posTransactionId": {POS-TRANSACTION-ID},
"rawResponse": {POS-RAW-RESPONSE}
},
"paymentPurchased": true
}
}
}
Cevap İçeriği | |
---|---|
Content-Type Başlığı |
application/json |
result alanı |
Bu alan içerisinde istek sonucu döner. 'ok’ ise işlem başarılı olmuştur. |
code alanı |
Bu alan içerisinde istek sonuç kodu döner. İşlem listesi isteği hata kodları için tıklayın. |
data alanı |
Bu alan postAuth cevabını içerir. |
data İçeriği |
|
---|---|
bkmTokenId alanı |
Bu alan {TICKET-ID} değerini içerir |
totalAmount alanı |
Bu alan gönderilen toplam tutar değerini içerir |
posResult alanı |
Pos'dan alınan sonuç bilgisini içerir |
paymentPurchased alanı |
Posta yapılan işlemin durumunu içerir. true işlem başarıyla tamamlandı. false Pos'tan hata alındı. |
data .posResult İçeriği |
|
---|---|
posResponse alanı |
Pos sonuç bilginisini APPROVED, FAILED içerir. |
posResultCode alanı |
Pos cevap kodunu içerir. |
orderId alanı |
Ödeme sipariş bilgisini içerir. |
posTransactionId alanı |
transaction id bilgisini içerir. |
rawResponse alanı |
Bankadan gelen ham cevabı içerir. |
Hata Kodları
KOD | AÇIKLAMA |
---|---|
OK-COM-001 | Başarıyla Tamamlandı. |
EX-FE-CON-009 | id ya da signature parametresi eksik. |
EX-MS-MRC-002 | İş yeri id bilgisi yanlış. |
EX-MS-MRC-004 | İş yeri imzalama hatası. |
EX-COM-001 | İş yeri imzalama formatı hatalı. |
EX-COM-002 | Yapılan istekteki parametreler kontrol edilmeli. |
EX-MER-COM-021 | Ticket ( ticketId ) parametresi eksik. |
EX-MER-COM-022 | Toplam tutar ( totalAmount ) gönderimi zorunludur. |
EX-MER-COM-023 | Gönderilen toplam tutar ( totalAmount ) formatı geçerli değil. |
EX-MER-COM-024 | Pos kullanıcı bilgisi ( posUserId ) gönderimi zorunludur. |
EX-MER-COM-025 | Pos şifre bilgisi ( posPassword ) gönderimi zorunludur. |
EX-MER-COM-026 | Pos servis bağlantı bilgisi ( serviceUrl ) gönderimi zorunludur. |
EX-MER-COM-027 | Pos banka kodu bilgisi ( vposBankCode ) gönderimi zorunludur. |
EX-MER-COM-028 | Ön otorizasyon kapama işlemi için yetkiniz bulunmamaktadır. |
EX-MER-COM-029 | Ön otorizasyon kapama işlemi için yeterli parametre bulunamadı. |
EX-MS-POS-003 | Gönderilen ticket ( ticketId ) parametresi sistemde bulunamadı. |
EX-MS-POS-004 | Gönderilen sipariş numarası ( orderId ) ile sistemde bir eşleşme bulunamadı ! |
EX-MS-POS-005 | Gönderilen sipariş numarası ( orderId ) ile sistemde birden fazla eşleşme bulundu ! |
EX-MS-POS-006 | Ön otorizasyon kapama işlemi gönderilen banka kodu ve servis url için uygulanamaz. |
EX-MS-POS-008 | Gönderilen parametrelerle sanal pos bulunamadı. |
Normal Entegrasyon Kullananlar için Test Sanal POS Bilgileri
Taksit entegrasyonu olarak normal entegrasyonu kullanmakta olan iş yerleri ön otorizasyon kapama API isteğinde POS bilgilerini göndermeliler. Preprod ortamında testler sırasında aşağıdaki POS bilgileri kullanılabilir.
Banka | Bank ID | vposUserId | vposPassword | extra | serviceUrl |
---|---|---|---|---|---|
AKBANK | 0046 | akapi | TEST1234 | {“ClientId” : “100111222”, “storekey”: “TEST1234”} |
http://srvirt01:7200/akbank |
ZIRAATBANK | 0010 | bkmtest | TEST1691 | {“ClientId”:“190001691”, “storekey”:“TRPS1691”, “orderId”:“9073194”} |
http://srvirt01:7200/ziraat |
HALKBANK | 0012 | testapi | TEST1234 | {“ClientId”:“500020009”, “storekey”:“Ab123456”} |
http://srvirt01:7200/halkbank |
VAKIFBANK | 0015 | 000000000011429 | BKMexpress | {“posno”:“vp000263”} | https://onlineodemetest.vakifbank.com.tr:4443/VposService/v3/Vposreq.aspx |
TEBBANK | 0032 | bkmapi | KUTU8520 | {“ClientId”:“401562930”, “storekey”:“KUTU8520”} |
http://srvirt01:7200/teb |
GARANTI | 0062 | 600218 | 123qweASD | {“terminalprovuserid”:“PROVAUT”, “terminalmerchantid”:“7000679”, “storekey”:“12345678”, “terminalid”:“30690168”} |
http://srvirt01:7200/VPServlet |
ISBANK | 0064 | bkmapi | KUTU8900 | {“ClientId”:“700655047520”, “storekey”:“TEST123456”} |
http://srvirt01:7200/isbank |
YKB | 0067 | bkm3d1 | 12345 | {“mid”:“6706598320”, “tid”: “67245089”, “posnetID”: “4280”} 3D orderId 24 karakter olmalı, 3D sizde 20 karakter |
http://srvirt01:7200/PosnetWebService/XML |
FINANSBANK | 0111 | bkmapi | TEST1234 | {“ClientId”:“600000120”, “storekey”:“TEST1234”} |
http://srvirt01:7200/finans |
QNBFINANSBANK yeni | 0111 | QNB_API_KULLANICI_3DPAY | UcBN0 | {“MbrId”:“5”,“MerchantId”:“085300000009704”} | https://vpostest.qnbfinansbank.com/Gateway/Default.aspx |
DENIZBANK | 0134 | 1 | 12345 | {“ShopCode”:“3123”, “UserCode”:“InterTestApi”, “UserPass”:“3”, “storeKey”:“gDg1N”} |
http://srvirt01:7200/mpi/Default.aspx |
Not: ING, HSBC, Odea, Kuveyt Türk ve TFKB bilgileri için lütfen iletişime geçiniz.
İmzalama ve Şifreleme
İmza oluşturulurken “SHA-256 with RSA” şifreleme yöntemi kullanılmalı ve BKM tarafına ilettiğiniz public key ile eşleşen private key kullanılmalı.
İmzalama ve Şifreleme için Kullanılacak Class
İmzalama ve şifreleme işlemleri için EncryptionUtil
class'ını kullanın.
// Java EncryptionUtil sınıfı
import javax.crypto.Cipher;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Arrays;
import java.util.Base64;
import java.util.LinkedHashMap;
import java.util.Map;
public final class EncryptionUtil {
private static final PublicKey PUBLIC_KEY;
static {
PUBLIC_KEY = getPublicKeyFromString(
"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuZj/TQ9ZRY5KnsA3HMPq" +
"bNwI32J+Bisyv7KX7IRJh5rN5LW3g7t6pulArLIEU3sn28ZQEQ+GCb9yvk6zIUoq" +
"KBqH0H+gvxOtsklOUkFRgh+/FghNDoe0OzkXTLjQKhh6MRMBR9l3cws9nA2cu+M5" +
"kw67F8j0+4SogHJ+VS1wA2kfWx58PNDIg9DtAVwmD1JbjAziPONv0wHSa8oNgia9" +
"Tx6ia6FS4nfjRNqpVqI0m2jIcG8yXt1OaBSazkuRlRepMtDVwMGF4xOWXuRVv+G5" +
"oiTsbOez9tQAcx+KH0W1Pn9Q9/zzOJyF9AS8J1UDE7c7rKwXGDnuTBU1BwdAGyB8" +
"7QIDAQAB"
);
java.security.Security.addProvider(
new org.bouncycastle.jce.provider.BouncyCastleProvider()
);
}
public static String sign(String privateKey, String data) {
try {
Signature rsaSignature = Signature.getInstance("SHA256withRSA");
PrivateKey pk = getPrivateKeyFromString(privateKey);
rsaSignature.initSign(pk);
rsaSignature.update(data.getBytes());
return encode64(rsaSignature.sign());
} catch (NoSuchAlgorithmException | SignatureException | InvalidKeyException e) {
e.printStackTrace();
}
return null;
}
public static String encryptWithBex(String dataStr) {
byte[] data = dataStr.getBytes(StandardCharsets.UTF_8);
StringBuilder encypted = new StringBuilder();
for (int i = 0; i <= data.length / 245; i++) {
byte[] subData = Arrays.copyOfRange(data, i * 245, (i + 1) * 245);
String subEncrypted = encrypt(PUBLIC_KEY, subData);
encypted.append(subEncrypted).append("|:*:|");
}
return encypted.toString();
}
public static String encrypt(PublicKey key, byte[] plaintext) {
try {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, key);
return encode64(cipher.doFinal(plaintext));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static byte[] decrypt(PrivateKey key, byte[] ciphertext) {
try {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, key);
return cipher.doFinal(ciphertext);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static boolean verifyBexSign(String data, String signature) {
try {
Signature rsaSignature = Signature.getInstance("SHA256withRSA");
rsaSignature.initVerify(PUBLIC_KEY);
rsaSignature.update(data.getBytes());
return rsaSignature.verify(decode64(signature));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (SignatureException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
}
return false;
}
private static PrivateKey getPrivateKeyFromString(String privateKey) {
try {
byte[] privateBytes = decode64(privateKey);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePrivate(keySpec);
} catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
e.printStackTrace();
}
return null;
}
private static PublicKey getPublicKeyFromString(String publicKey) {
try {
byte[] publicBytes = decode64(publicKey);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePublic(keySpec);
} catch (InvalidKeySpecException | NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
private static String encode64(byte[] data) {
return new String(Base64.getEncoder().encode(data));
}
private static byte[] decode64(String data) {
return Base64.getDecoder().decode(data);
}
}
<?php
class EncryptionUtil
{
const FORMATTED_PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuZj/TQ9ZRY5KnsA3HMPqbNwI32J+Bisyv7KX7IRJh5rN5LW3g7t6pulArLIEU3sn28ZQEQ+GCb9yvk6zIUoqKBqH0H+gvxOtsklOUkFRgh+/FghNDoe0OzkXTLjQKhh6MRMBR9l3cws9nA2cu+M5kw67F8j0+4SogHJ+VS1wA2kfWx58PNDIg9DtAVwmD1JbjAziPONv0wHSa8oNgia9Tx6ia6FS4nfjRNqpVqI0m2jIcG8yXt1OaBSazkuRlRepMtDVwMGF4xOWXuRVv+G5oiTsbOez9tQAcx+KH0W1Pn9Q9/zzOJyF9AS8J1UDE7c7rKwXGDnuTBU1BwdAGyB87QIDAQAB";
public static function sign($privateKey, $data)
{
$result = openssl_sign($data, $signature, self::getPrivateKeyFromString($privateKey), "sha256WithRSAEncryption");
if (!$result) {
throw new Exception("Sign error");
}
return base64_encode($signature);
}
private static function getPrivateKeyFromString($privateKey, $passphrase = "")
{
$result = openssl_pkey_get_private(self::formatKey($privateKey, "private"), $passphrase);
if (!$result) {
throw new Exception("Invalid key specification");
}
return $result;
}
private static function formatKey($unformattedKey, $keyType)
{
$result = "";
$lineCharacter = 0;
if ($keyType == "public") {
$lineCharacter = 64;
$result = wordwrap($unformattedKey, $lineCharacter, "\n", true);
$result = "-----BEGIN PUBLIC KEY-----\n" . $result . "\n-----END PUBLIC KEY-----";
} else {
$lineCharacter = 65;
$result = wordwrap($unformattedKey, $lineCharacter, "\n", true);
$result = "-----BEGIN RSA PRIVATE KEY-----\n" . $result . "\n-----END RSA PRIVATE KEY-----";
}
return $result;
}
public static function verifyBexSign($ticketId, $signature)
{
$result = openssl_verify($ticketId, base64_decode($signature), self::getPublicKeyFromString(self::FORMATTED_PUBLIC_KEY), "sha256WithRSAEncryption");
if ($result == 1) {
return true;
} else if ($result == 0) {
return false;
} else {
throw new Exception(openssl_error_string());
}
return true;
}
private static function getPublicKeyFromString($publicKey)
{
$result = openssl_pkey_get_public(self::formatKey($publicKey, "public"));
if (!$result) {
throw new Exception("Invalid key specification");
}
return $result;
}
public static function encryptWithBex($vposConfig)
{
//Assumes 1024 bit key and encrypts in chunks.
$maxlength = 245;
$i = 0;
$encryptedArray = [];
while ($vposConfig && $vposConfig !== "") {
$input = substr($vposConfig, 0, $maxlength);
$vposConfig = substr($vposConfig, $maxlength);
$result = EncryptionUtil::encryptBex($input);
if ($result) {
$encryptedArray[$i] = $result;
} else {
throw new Exception("Invalid key specification");
break;
}
$i++;
}
return join("|:*:|", $encryptedArray);
}
public static function encryptBex($parameter)
{
if (openssl_public_encrypt($parameter, $encrypted, self::getPublicKeyFromString(self::FORMATTED_PUBLIC_KEY))) {
$data = base64_encode($encrypted);
} else {
throw new Exception("Invalid key specification");
}
return $data;
}
}
?>
using Org.BouncyCastle.Security;
using System;
using System.Text;
using Org.BouncyCastle.Crypto;
using BexCsharpSDK.Merchant.Request;
using System.Security.Cryptography;
using Org.BouncyCastle.Crypto.Encodings;
using Org.BouncyCastle.Crypto.Engines;
using System.Linq;
namespace BexCsharpSDK.Merchant.Security
{
/// <summary>
/// This class provides two methods for signing data, and verifing data.
/// </summary>
public sealed class EncryptionUtil
{
private static string PublicKey = @"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuZj/TQ9ZRY5KnsA3HMPq" +
@"bNwI32J+Bisyv7KX7IRJh5rN5LW3g7t6pulArLIEU3sn28ZQEQ+GCb9yvk6zIUoq" +
@"KBqH0H+gvxOtsklOUkFRgh+/FghNDoe0OzkXTLjQKhh6MRMBR9l3cws9nA2cu+M5" +
@"kw67F8j0+4SogHJ+VS1wA2kfWx58PNDIg9DtAVwmD1JbjAziPONv0wHSa8oNgia9" +
@"Tx6ia6FS4nfjRNqpVqI0m2jIcG8yXt1OaBSazkuRlRepMtDVwMGF4xOWXuRVv+G5" +
@"oiTsbOez9tQAcx+KH0W1Pn9Q9/zzOJyF9AS8J1UDE7c7rKwXGDnuTBU1BwdAGyB8" +
@"7QIDAQAB";
/// <summary>
/// Sign data with your private key.
/// </summary>
/// <param name="privateKeyString">Your private key</param>
/// <param name="data">Data to sign</param>
/// <returns></returns>
public static string Sign(string privateKeyString, string data)
{
var privateKey = PrivateKeyFactory.CreateKey(Convert.FromBase64String(privateKeyString));
var bytes = new ASCIIEncoding().GetBytes(data);
ISigner signer = SignerUtilities.GetSigner("SHA256withRSA");
signer.Init(true, privateKey);
signer.BlockUpdate(bytes, 0, bytes.Length);
var signature = signer.GenerateSignature();
return Convert.ToBase64String(signature);
}
/// <summary>
/// Verify incoming data with incoming signature
/// </summary>
/// <param name="data">Data to verify</param>
/// <param name="signature">Verify data with this parameter</param>
/// <returns></returns>
public static bool VerifyBexSignature(string data, string signature)
{
var dataBytes = new ASCIIEncoding().GetBytes(data);
var signatureBytes = Convert.FromBase64String(signature);
ISigner signer = SignerUtilities.GetSigner("SHA256withRSA");
var publicKey = PublicKeyFactory.CreateKey(Convert.FromBase64String(PublicKey));
signer.Init(false, publicKey);
signer.BlockUpdate(dataBytes, 0, dataBytes.Length);
return signer.VerifySignature(signatureBytes);
}
public static string EncryptWithBex(string data)
{
var dataBytes = new ASCIIEncoding().GetBytes(data);
var encrypted = new StringBuilder();
for (int i = 0; i <= dataBytes.Length / 245; i++)
{
var sub = dataBytes.Skip(i * 245).Take(245).ToArray<byte>();
var subEncrypted = Encrypt(sub);
encrypted.Append(subEncrypted).Append("|:*:|");
}
return encrypted.ToString();
}
public static string EncryptWithBex(string data)
{
return Encrypt(new ASCIIEncoding().GetBytes(data));
}
public static string Encrypt(byte[] data)
{
var engine = new Pkcs1Encoding(new RsaEngine());
var publicKey = PublicKeyFactory.CreateKey(Convert.FromBase64String(PublicKey));
engine.Init(true, publicKey);
var encrypted = engine.ProcessBlock(data, 0, data.Length);
return Convert.ToBase64String(encrypted);
}
}
}
İmza oluşturma
EncryptionUtil
class'ını kullanarak SIGNATURE
oluşturun.
// Java EncryptionUtil sınıfı kullanılarak örnek imzalama işlemi
// Sign signature
String privateKey = "...";
String signature = EncryptionUtil.sign(privateKey, {MERCHANT-ID});
<?php
// PHP EncryptionUtil sınıfı kullanılarak örnek imzalama işlemi
// Sign signature
$privateKey = "...";
EncryptionUtil::sign({MERCHANT-ID}, $privateKey);
?>
// CSharp EncryptionUtil sınıfı kullanılarak örnek imzalama işlemi
// Sign signature
string PrivateKey = "...";
string Signature = EncryptionUtil.Sign(PrivateKey, {MERCHANT-ID});
Örnek İmzalama İşlemi | Değişken | Açıklama |
---|---|---|
PRIVATE KEY | {PRIVATE-KEY} | MIICdgIB…xolJg== |
DATA | {MERCHANT-ID} | 219be6b7-b3ca-4bd1-9886-a16d40b0bfe2 |
BEKLENEN SONUÇ | {SIGNATURE} | IGNoNOR/qq+GSQBJBsBuaTgNEWl…/KUye2dR4P8ut6WmZ4qbqE= |
Şifreleme
EncryptionUtil
class'ını kullanarak EXTRA
parametrelerini şifreleyin.
// Java EncryptionUtil kullanılarak örnek şifreleme işlemi
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
Map<String, String> extraMap = new LinkedHashMap<>();
extraMap.put("customItems", "%3CItem%20name%3D%22ACENTE_KODU%22%20value%3D%2221016%22%3E%3C%2FItem%3E%0A%3CItem%20name%3D%22MUSTERI%22%20value%3D%226210060402%22%3E%3C%2FItem%3E%0A%3CItem%20name%3D%22POLICE_NO%22%20value%3D%22243149023%22%3E%3C%2FItem%3E%0A%3CItem%20name%3D%22SUBE_KODU%22%20value%3D%222101500009%22%3E%3C%2FItem%3E%0A%3CItem%20name%3D%22URUN%22%20value%3D%2237101-Emtia%20Nakli(Abonman%20szle%C5%9Fmesine%20ba%C4%9Fl%C4%B1)%22%3E%3C%2FItem%3E%0A%3CItem%20name%3D%22KOMISYON%22%20value%3D%226.12%22%3E%3C%2FItem%3E%0A%3CItem%20name%3D%22SICIL%22%20value%3D%2228284%22%3E%3C%2FItem%3E%0A");
extraMap.put("Cari_Pol_No", "123ZE");
try{
String extraJsonString = new ObjectMapper().writeValueAsString(extraMap);
String encryptedExtra EncryptionUtil.encryptWithBex(extraJsonString);
}catch(Exception e) {
throw new RuntimeException(e);
}
<?php
// PHP EncryptionUtil kullanılarak örnek şifreleme işlemi
$extraMap = array(
"customItems" => "%3CItem%20name%3D%22ACENTE_KODU%22%20value%3D%2221016%22%3E%3C%2FItem%3E%0A%3CItem%20name%3D%22MUSTERI%22%20value%3D%226210060402%22%3E%3C%2FItem%3E%0A%3CItem%20name%3D%22POLICE_NO%22%20value%3D%22243149023%22%3E%3C%2FItem%3E%0A%3CItem%20name%3D%22SUBE_KODU%22%20value%3D%222101500009%22%3E%3C%2FItem%3E%0A%3CItem%20name%3D%22URUN%22%20value%3D%2237101-Emtia%20Nakli(Abonman%20szle%C5%9Fmesine%20ba%C4%9Fl%C4%B1)%22%3E%3C%2FItem%3E%0A%3CItem%20name%3D%22KOMISYON%22%20value%3D%226.12%22%3E%3C%2FItem%3E%0A%3CItem%20name%3D%22SICIL%22%20value%3D%2228284%22%3E%3C%2FItem%3E%0A",
"Cari_Pol_No" => "123ZE"
);
$encryptedExtra = EncryptionUtil::encryptWithBex(json_encode($extraMap));
?>
// CSharp EncryptionUtil kullanılarak örnek şifreleme işlemi
using Newtonsoft.Json;
var extraMap = new Dictionary<string, double>();
// Initialise to zero...
extraMap["customItems"] = "%3CItem%20name%3D%22ACENTE_KODU%22%20value%3D%2221016%22%3E%3C%2FItem%3E%0A%3CItem%20name%3D%22MUSTERI%22%20value%3D%226210060402%22%3E%3C%2FItem%3E%0A%3CItem%20name%3D%22POLICE_NO%22%20value%3D%22243149023%22%3E%3C%2FItem%3E%0A%3CItem%20name%3D%22SUBE_KODU%22%20value%3D%222101500009%22%3E%3C%2FItem%3E%0A%3CItem%20name%3D%22URUN%22%20value%3D%2237101-Emtia%20Nakli(Abonman%20szle%C5%9Fmesine%20ba%C4%9Fl%C4%B1)%22%3E%3C%2FItem%3E%0A%3CItem%20name%3D%22KOMISYON%22%20value%3D%226.12%22%3E%3C%2FItem%3E%0A%3CItem%20name%3D%22SICIL%22%20value%3D%2228284%22%3E%3C%2FItem%3E%0A";
extraMap["Cari_Pol_No"] = "123ZE";
var encryptedExtra = EncryptionUtil.encryptWithBex(JsonConvert.SerializeObject(extraMap));
3. Adres Entegrasyonu
BKM Express üzerinden kullanıcılarınızın adres bilgilerini alarak ödeme işlemini sağlayabilirsiniz.
Adres Entegrasyonu akışının çalışması için https://test-api.bkmexpress.com.tr/docs/ sayfasında yer alan entagrasyon adımlarının tümünün tamamlanmış olması gerekmektedir. Aşağıdaki adımlar ise adres entegrasyonunu kullanabilmeniz için yapmanız gereken değişikliklerdir.
- Adres Entegrasyonu akışının çalışması için Ticket Token üretilirken “addres” alanının değeri “true” olarak gönderilmelidir.
- Adres Entegrasyonu akışı başlatılan bir işlem için, kullanıcı BKM Express uygulamasında OTP kodunu girip ödemesini tamamlamak istediğinde iş yeri server’ına yapılan Nonce çağrısı içerisinde kullanıcının seçtiği adres bilgisi iş yerine gönderilir.
- İş yerinin bu adres bilgisini alması ve gerekli kontrollerini yapıp nonce’ı onaylaması beklenmektedir.
- Nonce sürecinde ödemenin başarılı geçildiği bilgisi iş yerine iletildiğinde, daha önce iletilen adres bilgisi ile iş yerinin siparişi tamamlaması gerekmektedir.
ÖNEMLİ Kullanıcı adresi BKM Express içerisinde seçtiğinden kullanıcıya onaylatacağınız mesafeli satış sözleşmesi ve ön bilgilendirme formu, BKM Express içerisinde adres seçildikten sonra görüntülenecektir. Bu nedenle Mesafeli Satış Sözleşmesi ve Ön Bilgilendirme Formu adımını da tamamlamanız gerekmektedir.
2.1 Builder Kullanılarak Ticket Token Üretilmesi (Sipariş Numarası, Kampanya Kodu, TCKN, Email ve Adres Entegrasyonu Kullanımı Bilgilerinin Gönderilmesi)
<?php
use Bex\merchant\request\Builder;
//Builder kullarak TicketToken Üretilmesi
$builder = Builder::newPayment("payment");
$builder->amount("1000,56"); // zorunlu (Ödeme Tutarı)
$builder->installmentUrl("https://isyeri.com/installment"); // opsiyonel ("SIZIN SERVER'INIZDA TAKSITLERI SORGULAMAK ICIN BIR URL")
$builder->nonceUrl("https://isyeri.com/nonce"); // zorunlu ("SIPARISIN UYGUNLUGUNUN KONTROL EDILMESI ICIN URL")
$builder->campaignCode("BKM1234"); // opsiyonel (Kampanya Kodu)
$builder->orderId("123456"); // opsiyonel. ( Sipariş Numarası - Her Ticket isteği için farklı bir değer içermeli)
$builder->tckn("10000000146", true); // opsiyonel (number => "TC Kimlik Numarası", check => "BKM Express içerisinde kontrol edilsin mi")
$builder->msisdn("5051234567", true); // opsiyonel ('no' => "cep telefonu numarası", 'check' => "BKM Express içerisinde kontrol edilsin mi")
$builder->address(true); // opsiyonel (adres entegrasyonları kullananlar için)
$builder->agreementUrl("https://isyeri.com/agreement"); // opsiyonel ("Mesafeli satış ve ön bilgilendirme formu için sizin sitenize yönlenecek url") adres entegrasyonları için zorunlu
?>
request = TicketRequest.Builder.newPayment()
.amount("1000,56")
.orderId("123456")
.campaignCode("my campaign")
.installmentUrl("https://isyeri.com/installment")
.nonceUrl("https://isyeri.com/nonce")
.tckn("10000000146", true)
.msisdn("5051234567", true)
.agreementUrl("https://isyeri.com/agreement")
.address(true)
.build();
Token ticket = bex.merchantService().createOneTimeTicket(connection, tr); (edited)
ticketRequest = new TicketRequest.Builder()
.newPayment()
.orderId("123456") // sipariş numarası
.amount("1000,56") // sipariş toplam tutarı
.campaignCode("my campaign") // kampanya kodu
.installmentUrl("https://isyeri.com/installment")
.nonceUrl("https://isyeri.com/nonce")
.tckn("10000000146", true)) // kullanıcının tck kimlik numarası ve BKM Express içerisinde kontrol edilsin mi bilgisi
.msisdn("5051234567", true)) // kullanıcının tck kimlik numarası ve BKM Express içerisinde kontrol edilsin mi bilgisi
.agreementUrl("https://isyeri.com/agreement")
.address(true)
.build();
Token ticket = bex.GetMerchantService().OneTimeTicket(connection, tr);
Tikcet Token'ı üretirken sipariş numarası, kampanya kodu, kullanıcının TC Kimlik Numarası ve email bigilerini gönderebilmek için Ticket Token'ı builder kullanarak üretmelisiniz.
1. Sipariş numarası (orderId): corderId banka tarafına iletilen sipariş numarasıdır. Her Ticket oluşturma isteği için farklı bir orderId değeri göndermelisiniz. OrderId göndermediğiniz durumda sipariş numarası olarak bankaya sistemde üretilen bir değer gönderilir. İşlem sonucunda bu değer size iletilir.
2. Kampanya Numarası (campaignCode): BKM Express ile bir kampanya anlaşmanız bulunması halinde sipariş için oluşturduğunuz kampanya kodunu bu alanda göndermelisiniz.
3. Kullanıcının TC Kimlik Numarası (tckn): Kullanıcının elinizdeki TCKN bilgisini BKM Express'e iletebilir ve TCKN kontrolü yapılmasını isteyebilirsiniz. Kullanımı için bkz. 2.2 Siparişin Uygunluğunu Kontrol Edin (Nonce)
4. Kullanıcının Telefon Numarası (msisdn): Kullanıcının elinizdeki cep telefonu numarası bilgisini BKM Express'e iletebilir ve cep telefonu kontrolü yapılmasını isteyebilirsiniz. Kullanımı için bkz. 2.2 Siparişin Uygunluğunu Kontrol Edin (Nonce)
5. Adres entegrasyonu(address): Adres entegrasyonu yapmak isteyen işyerlerinin ticket oluşurken bu bilgiyi iletmesi gerekmektedir. Eğer address alanı true olarak iletilirse, NonceRequest içerisinde işyerine kullanıcının seçtiği adres bilgisi iletilir. Address bilgisini ileten işyerleri agreementUrl değişkenini de iletmelidir.
6. Sözleşme url'i(agreementUrl): Mesafeli satış sözleşmesi ve önbilgilendirme formununun güncel halini ödeme aşamasından önce göstermek isteyen işyerleri, sözleşmeyi kendi siteleri üzerinde göstermek için bir url iletilir. Adres bilgileri nonce aşamasına gelmeden verdiğiniz url'e post edilir ve bu istek sonucunda dönen html kullanıcıya gösterilir.
<?php
//Ticket oluşturulurken adres entegrasyonu için paremetrenin geçilmesi
$builder = Builder::newPayment("payment");
$builder->amount("1000,56"); // zorunlu (Ödeme Tutarı)
$builder->installmentUrl("https://isyeri.com/installment"); // opsiyonel ("SIZIN SERVER'INIZDA TAKSITLERI SORGULAMAK ICIN BIR URL")
$builder->nonceUrl("https://isyeri.com/nonce"); // zorunlu ("SIPARISIN UYGUNLUGUNUN KONTROL EDILMESI ICIN URL")
$builder->address(true); // opsiyonel (adres entegrasyonları kullananlar için)
$builder->agreementUrl("https://isyeri.com/agreement"); // opsiyonel ("Mesafeli satış ve ön bilgilendirme formu için sizin sitenize yönlenecek url") adres entegrasyonları için zorunlu
$ticketResponse = $merchantService->oneTimeTicketWithBuilder($merchantResponse->getToken(), $builder);
?>
//Ticket oluşturulurken adres entegrasyonu için paremetrenin geçilmesi
request = TicketRequest.Builder.newPayment()
.amount("1000,56")
.installmentUrl("https://isyeri.com/installment")
.nonceUrl("https://isyeri.com/nonce")
.agreementUrl("https://isyeri.com/agreement")
.address(true)
.build();
Token ticket = bex.merchantService().createOneTimeTicket(connection, tr); (edited)
//Ticket oluşturulurken adres entegrasyonu için paremetrenin geçilmesi
ticketRequest = new TicketRequest.Builder()
.newPayment()
.amount("1000,56") // sipariş toplam tutarı
.campaignCode("my campaign") // kampanya kodu
.installmentUrl("https://isyeri.com/installment")
.nonceUrl("https://isyeri.com/nonce")
.agreementUrl("https://isyeri.com/agreement")
.address(true)
.build();
Token ticket = bex.GetMerchantService().OneTimeTicket(connection, tr);
<?php
class NonceRequest {
...
public function getDeliveryAddress()
{
return $this->reply->deliveryAddress;
}
public function getBillingAddress()
{
return $this->reply->billingAddress;
}
}
?>
// Nonce request içerisinde aşağıdaki gibi Address alanları iletilecektir.
public class NonceRequest {
...
public Address getDeliveryAddress() {
return this.reply.getDeliveryAddress();
}
public Address getBillingAddress() {
return this.reply.getBillingAddress();
}
...
}
// Nonce request'inde fatura ve teslimat adreslerine aşağıdaki şekilde erişebilirsiniz.
request.billingAddress;
request.deliveryAddress;
<?php
class Address
{
private $addressType;
private $name;
private $surname;
private $companyName;
private $address;
private $telephone;
private $taxNumber;
private $taxOffice;
private $county;
private $city;
private $tckn;
private $email;
..
}
class AddressType
{
const INDIVIDUAL = "B";
const CORPORATE = "K";
}
public class Address {
private AddressType addressType;
private String name;
private String surname;
private String companyName;
private String address;
private String telephone;
private String taxNumber;
private String taxOffice;
private String county;
private String city;
private String tckn;
private String email;
....
}
public enum AddressType {
B("individual"),
K("corporate");
...
}
public class Address
{
public enum AddressType {B, K}
public AddressType addressType { get; set; }
public String name { get; set; }
public String surname { get; set; }
public String companyName { get; set; }
public String address { get; set; }
public String telephone { get; set; }
public String taxNumber { get; set; }
public String taxOffice { get; set; }
public String county { get; set; }
public String city { get; set; }
public String tckn { get; set; }
public String email { get; set; }
}
2.2 Siparişin Uygunluğunu Kontrol Edin (Nonce)
Nonce sırasında kullanıcının adresine ilişkin size iletilecek bilgiler;
Alan Adı | Açıklama |
String email | e-posta adresi->login olduğu mail adresi bilgisi |
AddressType addressType | adres tipi -> B ya da K olabilir. B : bireysel K: kurumsal.Bireysel için tckn değeri zorunludur. Kurumsal için taxOffice,taxNumber ve companyName değerleri zorunludur. |
String ad | ad |
String surname | soyad |
String address | adres -> Adress entegrasyonu kullanılacaksa bu değer true olmalı. Kullanılmayacaksa iletilmemelidir. |
String county | ilçe -> adrese ait ilçe |
String city | il -> adrese ait il |
String telephone | telefon numarası |
String tckn | ilçe -> adress tipi bireysel olması durumunda doldurulması zorunlu alan |
String companyName | ilçe -> adress tipi kurumsal olması durumunda doldurulması zorunlu alan |
String taxNumber | ilçe -> adress tipi kurumsal olması durumunda doldurulması zorunlu alan.Vergi kimlik numarası. |
String taxOffice | ilçe -> adress tipi kurumsal olması durumunda doldurulması zorunlu alan.Vergi dairesi adı. |
Mesafeli Satış Sözleşmesi ve Ön Bilgilendirme Formu’nun BKM Express’te Gösterilmesi
//BKM Express tarafından iframe içerisinden agreement url'e yapılacak istek
curl 'https://isyeri.com/agreementUrl' --data '
ticketId=17355c4c-f3a3-4573-9780-fb38dd7eee0a&
orderId=17355c4c-f3a3-4573-9780-fb38dd7eee0a&
amount=1000%2C52&
deliveryAddress.addressType=B&
deliveryAddress.city=%C4%B0zmir&
deliveryAddress.address=qweqwq&
deliveryAddress.companyName=&
deliveryAddress.county=Bay%C4%B1nd%C4%B1r&
deliveryAddress.email=zeynep%40bkm.com&
deliveryAddress.name=weqeqe&
deliveryAddress.surname=qweqwe&
deliveryAddress.taxNumber=&
deliveryAddress.taxOffice=&
deliveryAddress.tckn=44444444444&
deliveryAddress.telephone=5333333333&
billingAddress.addressType=B&
billingAddress.city=%C4%B0zmir&
billingAddress.address=qweqwq&
billingAddress.companyName=&
billingAddress.county=Bay%C4%B1nd%C4%B1r&
billingAddress.email=zeynep%40bkm.com&
billingAddress.name=weqeqe&
billingAddress.surname=qweqwe&
billingAddress.taxNumber=&
billingAddress.taxOffice=&
billingAddress.tckn=44444444444&
billingAddress.telephone=5333333333' --compressed
//BKM Express tarafından iframe içerisinden agreement url'e yapılacak istek
curl 'https://isyeri.com/agreementUrl' --data '
ticketId=17355c4c-f3a3-4573-9780-fb38dd7eee0a&
orderId=17355c4c-f3a3-4573-9780-fb38dd7eee0a&
amount=1000%2C52&
deliveryAddress.addressType=B&
deliveryAddress.city=%C4%B0zmir&
deliveryAddress.address=qweqwq&
deliveryAddress.companyName=&
deliveryAddress.county=Bay%C4%B1nd%C4%B1r&
deliveryAddress.email=zeynep%40bkm.com&
deliveryAddress.name=weqeqe&
deliveryAddress.surname=qweqwe&
deliveryAddress.taxNumber=&
deliveryAddress.taxOffice=&
deliveryAddress.tckn=44444444444&
deliveryAddress.telephone=5333333333&
billingAddress.addressType=B&
billingAddress.city=%C4%B0zmir&
billingAddress.address=qweqwq&
billingAddress.companyName=&
billingAddress.county=Bay%C4%B1nd%C4%B1r&
billingAddress.email=zeynep%40bkm.com&
billingAddress.name=weqeqe&
billingAddress.surname=qweqwe&
billingAddress.taxNumber=&
billingAddress.taxOffice=&
billingAddress.tckn=44444444444&
billingAddress.telephone=5333333333' --compressed
//BKM Express tarafından iframe içerisinden agreement url'e yapılacak istek
curl 'https://isyeri.com/agreementUrl' --data '
ticketId=17355c4c-f3a3-4573-9780-fb38dd7eee0a&
orderId=17355c4c-f3a3-4573-9780-fb38dd7eee0a&
amount=1000%2C52&
deliveryAddress.addressType=B&
deliveryAddress.city=%C4%B0zmir&
deliveryAddress.address=qweqwq&
deliveryAddress.companyName=&
deliveryAddress.county=Bay%C4%B1nd%C4%B1r&
deliveryAddress.email=zeynep%40bkm.com&
deliveryAddress.name=weqeqe&
deliveryAddress.surname=qweqwe&
deliveryAddress.taxNumber=&
deliveryAddress.taxOffice=&
deliveryAddress.tckn=44444444444&
deliveryAddress.telephone=5333333333&
billingAddress.addressType=B&
billingAddress.city=%C4%B0zmir&
billingAddress.address=qweqwq&
billingAddress.companyName=&
billingAddress.county=Bay%C4%B1nd%C4%B1r&
billingAddress.email=zeynep%40bkm.com&
billingAddress.name=weqeqe&
billingAddress.surname=qweqwe&
billingAddress.taxNumber=&
billingAddress.taxOffice=&
billingAddress.tckn=44444444444&
billingAddress.telephone=5333333333' --compressed
//BKM Express tarafından post ile yapılan isteğe cevap olarak dönmeniz gereken sözleşmeler için örnek html kodu
<!DOCTYPE HTML>
<html lang="en">
<head>
<style>
table {
border-collapse: collapse;
width: 100%;
font-size: small;
}
th, td {
padding: 8px;
text-align: left;
border-bottom: 1px solid #ddd;
}
</style>
</head>
<body>
<script>
function acceptAgreement() {
window.parent.postMessage("close", "*");
}
</script>
<div>
<div style=" padding: 10px;overflow: scroll;-webkit-overflow-scrolling: touch">
<h5 style="text-align: center;font-weight: bold;letter-spacing: 0.5px">
Yeni ekledigimiz ozelliklerle birlikte kullanici sozlesmemizi yeniledik.</h5>
<br/>
<div style="height: 365px">
<div>
<h4>Siparis Bilgisi</h4>
<table>
<tr>
<th>
Kalem
</th>
<th>
Deger
</th>
</tr>
<tr>
<td>ticketId:</td>
<td><?php echo $_POST['ticketId']; ?></td>
</tr>
<tr>
<td>orderId:</td>
<td> <?php echo $_POST['orderId']; ?></td>
</tr>
<tr>
<td>totalAmount:</td>
<td> <?php echo $_POST['amount']; ?></td>
</tr>
</table>
</div>
<div>
<h4>Teslimat Adresi Bilgisi</h4>
<table>
<tr>
<th>
Kalem
</th>
<th>
Deger
</th>
</tr>
<tr>
<td>Adres Tipi:</td>
<td><?php echo $_POST['deliveryAddress_addressType']; ?></td>
</tr>
<tr>
<td>Il :</td>
<td><?php echo $_POST['deliveryAddress_city']; ?></td>
</tr>
<tr>
<td>Ilce:</td>
<td><?php echo $_POST['deliveryAddress_county']; ?></td>
</tr>
<tr>
<td>Acik Adres :</td>
<td><?php echo $_POST['deliveryAddress_address']; ?></td>
</tr>
<tr>
<td>Şirket Unvani :</td>
<td><?php echo $_POST['deliveryAddress_companyName']; ?></td>
</tr>
<tr>
<td>Email :</td>
<td><?php echo $_POST['deliveryAddress_email']; ?></td>
</tr>
<tr>
<td>Ad:</td>
<td><?php echo $_POST['deliveryAddress_name']; ?></td>
</tr>
<tr>
<td>Soyad:</td>
<td><?php echo $_POST['deliveryAddress_surname']; ?></td>
</tr>
<tr>
<td>Vergi Kimlik Numarasi :</td>
<td><?php echo $_POST['deliveryAddress_taxNumber']; ?></td>
</tr>
<tr>
<td>Vergi Dairesi</td>
<td><?php echo $_POST['deliveryAddress_taxOffice']; ?></td>
</tr>
<tr>
<td>TCKN:</td>
<td><?php echo $_POST['deliveryAddress_tckn']; ?></td>
</tr>
<tr>
<td>Telefon Numarasi</td>
<td><?php echo $_POST['deliveryAddress_telephone']; ?></td>
</tr>
</table>
</div>
<div>
<h4>Fatura Adresi Bilgisi</h4>
<table>
<tr>
<td>Adres Tipi:</td>
<td><?php echo $_POST['billingAddress_addressType']; ?></td>
</tr>
<tr>
<td>Il :</td>
<td><?php echo $_POST['billingAddress_city']; ?></td>
</tr>
<tr>
<td>Ilce:</td>
<td><?php echo $_POST['billingAddress_county']; ?></td>
</tr>
<tr>
<td>Acik Adres :</td>
<td><?php echo $_POST['billingAddress_address']; ?></td>
</tr>
<tr>
<td>Şirket Unvani :</td>
<td><?php echo $_POST['billingAddress_companyName']; ?></td>
</tr>
<tr>
<td>Email :</td>
<td><?php echo $_POST['billingAddress_email']; ?></td>
</tr>
<tr>
<td>Ad:</td>
<td><?php echo $_POST['billingAddress_name']; ?></td>
</tr>
<tr>
<td>Soyad:</td>
<td><?php echo $_POST['billingAddress_surname']; ?></td>
</tr>
<tr>
<td>Vergi Kimlik Numarasi :</td>
<td><?php echo $_POST['billingAddress_taxNumber']; ?></td>
</tr>
<tr>
<td>Vergi Dairesi</td>
<td><?php echo $_POST['billingAddress_taxOffice']; ?></td>
</tr>
<tr>
<td>TCKN:</td>
<td><?php echo $_POST['billingAddress_tckn']; ?></td>
</tr>
<tr>
<td>Telefon Numarasi</td>
<td><?php echo $_POST['billingAddress_telephone']; ?></td>
</tr>
</table>
</div>
</div>
</div>
<div style="width:100%">
<input onclick='acceptAgreement()' style="width:1%" id="acceptCheck" name="acceptCheck" type="checkbox" />
<label for="acceptCheck">
<a>Kullanıcı sözleşmesini</a>okudum, anladım, kabul ediyorum.
</label>
</div>
</div>
</body>
</html>
//BKM Express tarafından post ile yapılan isteğe cevap olarak dönmeniz gereken sözleşmeler için örnek html kodu
<!DOCTYPE HTML>
<html lang="tr" xmlns="http://www.w3.org/1999/html">
<body>
<script>
function acceptAgreement() {
window.parent.postMessage("close", "*");
}
</script>
<div>
<div style=" padding: 10px;width: 360px;height: 380px;overflow: scroll;-webkit-overflow-scrolling: touch;border: thin dotted #d8d8d8;">
<h5 style="text-align: center;font-weight: bold;letter-spacing: 0.5px">
Yeni eklediğimiz özelliklerle birlikte kullanıcı sözleşmemizi yeniledik.</h5>
<br/>
<div>
ticketId: ${model.ticketId};
orderId: ${model.orderId};
totalAmount: ${model.amount};
billingAddress.addressType: ${model.billingAddress.addressType};
billingAddress.name: ${model.billingAddress.name};
billingAddress.surname: ${model.billingAddress.surname};
billingAddress.companyName: ${model.billingAddress.companyName};
billingAddress.address: ${model.billingAddress.address};
billingAddress.telephone: ${model.billingAddress.telephone};
billingAddress.taxNumber: ${model.billingAddress.taxNumber};
billingAddress.taxOffice: ${model.billingAddress.taxOffice};
billingAddress.county: ${model.billingAddress.county};
billingAddress.city: ${model.billingAddress.city};
billingAddress.tckn: ${model.billingAddress.tckn};
billingAddress.email: ${model.billingAddress.email};
deliveryAddress.addressType: ${model.deliveryAddress.addressType};
deliveryAddress.name: ${model.deliveryAddress.name};
deliveryAddress.surname: ${model.deliveryAddress.surname};
deliveryAddress.companyName: ${model.deliveryAddress.companyName};
deliveryAddress.address: ${model.deliveryAddress.address};
deliveryAddress.telephone: ${model.deliveryAddress.telephone};
deliveryAddress.taxNumber: ${model.deliveryAddress.taxNumber};
deliveryAddress.taxOffice: ${model.deliveryAddress.taxOffice};
deliveryAddress.county: ${model.deliveryAddress.county};
deliveryAddress.city: ${model.deliveryAddress.city};
deliveryAddress.tckn: ${model.deliveryAddress.tckn};
deliveryAddress.email: ${model.deliveryAddress.email};
</div>
</div>
<div style="width:100%">
<input onclick='acceptAgreement()' style="width:1%" id="acceptCheck" name="acceptCheck" type="checkbox" />
<label for="acceptCheck">
<a>Kullanıcı sözleşmesini</a>okudum, anladım, kabul ediyorum.
</label>
</div>
</div>
</body>
</html>
//BKM Express tarafından post ile yapılan isteğe cevap olarak dönmeniz gereken sözleşmeler için örnek html kodu
<!DOCTYPE HTML>
<html lang="tr" xmlns="http://www.w3.org/1999/html">
<body>
<script>
function acceptAgreement() {
window.parent.postMessage("close", "*");
}
</script>
<div>
<div style=" padding: 10px;width: 360px;height: 380px;overflow: scroll;-webkit-overflow-scrolling: touch;border: thin dotted #d8d8d8;">
<h5 style="text-align: center;font-weight: bold;letter-spacing: 0.5px">
Yeni eklediğimiz özelliklerle birlikte kullanıcı sözleşmemizi yeniledik.</h5>
<br/>
<div>
ticketId: ${model.ticketId};
orderId: ${model.orderId};
totalAmount: ${model.amount};
billingAddress.addressType: ${model.billingAddress.addressType};
billingAddress.name: ${model.billingAddress.name};
billingAddress.surname: ${model.billingAddress.surname};
billingAddress.companyName: ${model.billingAddress.companyName};
billingAddress.address: ${model.billingAddress.address};
billingAddress.telephone: ${model.billingAddress.telephone};
billingAddress.taxNumber: ${model.billingAddress.taxNumber};
billingAddress.taxOffice: ${model.billingAddress.taxOffice};
billingAddress.county: ${model.billingAddress.county};
billingAddress.city: ${model.billingAddress.city};
billingAddress.tckn: ${model.billingAddress.tckn};
billingAddress.email: ${model.billingAddress.email};
deliveryAddress.addressType: ${model.deliveryAddress.addressType};
deliveryAddress.name: ${model.deliveryAddress.name};
deliveryAddress.surname: ${model.deliveryAddress.surname};
deliveryAddress.companyName: ${model.deliveryAddress.companyName};
deliveryAddress.address: ${model.deliveryAddress.address};
deliveryAddress.telephone: ${model.deliveryAddress.telephone};
deliveryAddress.taxNumber: ${model.deliveryAddress.taxNumber};
deliveryAddress.taxOffice: ${model.deliveryAddress.taxOffice};
deliveryAddress.county: ${model.deliveryAddress.county};
deliveryAddress.city: ${model.deliveryAddress.city};
deliveryAddress.tckn: ${model.deliveryAddress.tckn};
deliveryAddress.email: ${model.deliveryAddress.email};
</div>
</div>
<div style="width:100%">
<input onclick='acceptAgreement()' style="width:1%" id="acceptCheck" name="acceptCheck" type="checkbox" />
<label for="acceptCheck">
<a>Kullanıcı sözleşmesini</a>okudum, anladım, kabul ediyorum.
</label>
</div>
</div>
</body>
</html>
//Kullanıcı sözleşmeyi onayladığında BKM Express uygulamasına dönüş için kullanılması gereken javascript fonksiyonu
<script>
function acceptAgreement() {
window.parent.postMessage("close", "*");
}
</script>
//Kullanıcı sözleşmeyi onayladığında BKM Express uygulamasına dönüş için kullanılması gereken javascript fonksiyonu
<script>
function acceptAgreement() {
window.parent.postMessage("close", "*");
}
</script>
//Kullanıcı sözleşmeyi onayladığında BKM Express uygulamasına dönüş için kullanılması gereken javascript fonksiyonu
<script>
function acceptAgreement() {
window.parent.postMessage("close", "*");
}
</script>
Adres ve ödeme bilgileri seçildikten sonra mesafeli satış sözleşmesi ve ön bilgilendirme formunu hukuki zorunluluklardan dolayı işyerinin sitesi üzerinde gösterilmesi gerekmektedir. Bunun için aşağıdaki adımları takip etmelisiniz;
- Ticket oluştururken gönderdiğiniz agreementUrl adresine BKM Express uygulaması içerisinde iframe açılıp, post ile adres ve işlem bilgileri iletilir.
- Bu aşamada post isteğini karşılayıp sayfanız üzerinde html ile sözleşmeleri göstermeniz gerekmektedir.
- Bu html içerisindeki sözleşmeleri kullanıcı onayladığında kendi sunucunuz üzerinde bu sözleşmelerin onaylandığını tutup, size vereceğimiz javascript kod örneği ile sözleşme onayını tamamlamalısınız.
- Sizden aldığımız onay ile BKM Express uygulamasında ödeme işlemine devam edilir.
4. İptal İade Servisi
BKM Express üzerinden gerçekleşen sanal pos işlemlerin İptal / İade sürecini sağlayan servistir.İptal / İade işlemleri işyeri tarafından referanslı işlemde token; işlem tipi ve tutar bilgisi ile başlatılır. İşyeri İptal / İade servisini her çağırdığında tekil (unique) bir referans numarası iletir, gerektiği durumlarda karşılıklı olarak işlemler bu tekil numara ile takip edilir.
İptal – iade hizmeti için kullanılacak olan web servislerin çalışma prensipleri aşağıdaki gibidir.
Merchant id ve s (imza) kontrolleri yapılır.
İptal / iade için iletilen işlemin o merchant id’ye ait olduğu kontrol edilir. Bir merchant id’ye ait işlemi sadece o merchant id gerçekleştirebilir.
İptal / iadeyi gerçekleştirmek için işlemin tarihi üzerinde bir kontrol yapılmaz. (Aynı gün-farklı gün kontrolü sanal pos’un bankası yapıyor)
İptal / iadeyi gerçekleştirmek için işlemin tutar kontrolü yapılmıyor. (Bu kontrolü sanal pos’un bankası yapıyor)
İptal / iade işleminin tekrar tekrar yapılabilmesi kontrolünü sanal posun bankası yapıyor.
Bu kontrollerden geçen işlemler için ;
İptal / iade isteğinde ihtiyaç duyulan alanlar sanal POS bazında işlem üzerinden alınarak, sanal POS’a iletilir.
Sanal POS’tan gelen cevap işyerine gönderilir.
doReversalWithRef Webservisi
Ödemesi BKM tarafından gerçekleştirilen işlemler için iptal –iade işlemlerinin gerçekleştirileceği web servistir. İşlem; tutar, işlem tipi ve token bilgileri ile başlatılır.
doReversalWithRef Preprod Endpoint Adresi:
https://preprod.bkmexpress.com.tr/BKMExpress/BKMExpressReversalRestService/reversalWithRef.do
doReversalWithRef Production Endpoint Adresi:
https://www.bkmexpress.com.tr/BKMExpress/BKMExpressReversalRestService/reversalWithRef.do
doReversalWithRef Request Parametreleri
İSTEK PARAMETRESİ | Tipi |
Zorunlu(m)/ Opsiyonel(o) |
Uzunluk | AÇIKLAMA |
uniqueReferans | String | m | 50 | doReversalWithNoRef işleminin referans numarası. |
merchantId | String | m | 36 | İşyeri merchant id’si. |
requestType | String | m | 1 | İptal için 1; iade için 2; gönderilmelidir. |
amount | String | m | 20 | İptal / iade edilecek tutar bilgisi. “0000,00” formatında iletilir. İptal işlemlerinde, tutarın önemi yoktur. Satıştaki işlem tutarı iptal edilir. |
currency | String | m | 3 | İşlemin döviz kodu. 949 gibi. |
posUid | String | c | 50 | POS’a giderken kullanılacak kullanıcı adıdır. |
posPwd | String | c | 50 | POS’a giderken kullanılacak şifredir. |
transactionToken | String | m | 50 | BKM tarafından ödemesi yapılmış işleme ait token bilgisi yazılır. |
extra | String | o | İptal iade işlemlerinde banka bazında gerekli olabilecek parametrelerin iletileceği alan(JSON formatta) | |
ts | String | m | 17 | yyyyMMdd-hh:mm:ss formatında |
s | String | m | Tüm alanların tablodaki sırayla concat edilerek “SHA-256 with RSA” ile imzalanmış hali -> “Extra” parametresini imzaya dahil etmeyiniz. |
//Normal entegrasyon için örnek doReversalWithRef Request İsteği:
{
"merchantId": "2CBB2A88-1768-4565-B052-7DF37738DBCF",
"requestType": "1",
"amount": "12,31",
"currency": "949",
"transactionToken": "78ccd398-6ff6-431c-beeb-f1c9a90a8a14",
"posUid": "akapi",
"posPwd": "TEST1234",
"extra": "{"ClientId":"100111222", "storekey":"TEST1234"}",
"uniqueReferans": "182709220424024254",
"ts": "20190118-14:51:33",
"s": "TKkP/kkIhgtj+2u8CiXRjsCtIuibNVBTQIk/bjMztx09nm0//AKjGRRT2kCjPzC1Yx7QUTRej/cCZE/jTWCrU/8W/jsojbgJO4MLjPOqLyI1B64FOKVeA9u1y+GUT9tN7XJTCTzpOz0OqqKqrTH1YNOKPlwslLfC22KzMB2KfIPCIUS+QFAVaIaGt4qjf4FAK7HcdDfU72eiY21cOuTzUbuQK+hsO5KEQY1B2j++04oeqvgKMkfejGHiM2nl0wcZwzQgJT9AOJvxWspJRVR1fA0gZobyOPrhlYWk48Fj0gTgTiggcdr3yYHyvCXrUHYD3RENY6mIhXF2/v0pFc++QQ=="
}
//Normal entegrasyon için örnek doReversalWithRef Request İsteği:
{
"merchantId": "2CBB2A88-1768-4565-B052-7DF37738DBCF",
"requestType": "1",
"amount": "12,31",
"currency": "949",
"transactionToken": "78ccd398-6ff6-431c-beeb-f1c9a90a8a14",
"posUid": "akapi",
"posPwd": "TEST1234",
"extra": "{"ClientId":"100111222", "storekey":"TEST1234"}",
"uniqueReferans": "182709220424024254",
"ts": "20190118-14:51:33",
"s": "TKkP/kkIhgtj+2u8CiXRjsCtIuibNVBTQIk/bjMztx09nm0//AKjGRRT2kCjPzC1Yx7QUTRej/cCZE/jTWCrU/8W/jsojbgJO4MLjPOqLyI1B64FOKVeA9u1y+GUT9tN7XJTCTzpOz0OqqKqrTH1YNOKPlwslLfC22KzMB2KfIPCIUS+QFAVaIaGt4qjf4FAK7HcdDfU72eiY21cOuTzUbuQK+hsO5KEQY1B2j++04oeqvgKMkfejGHiM2nl0wcZwzQgJT9AOJvxWspJRVR1fA0gZobyOPrhlYWk48Fj0gTgTiggcdr3yYHyvCXrUHYD3RENY6mIhXF2/v0pFc++QQ=="
}
//Normal entegrasyon için örnek doReversalWithRef Request İsteği:
{
"merchantId": "2CBB2A88-1768-4565-B052-7DF37738DBCF",
"requestType": "1",
"amount": "12,31",
"currency": "949",
"transactionToken": "78ccd398-6ff6-431c-beeb-f1c9a90a8a14",
"posUid": "akapi",
"posPwd": "TEST1234",
"extra": "{"ClientId":"100111222", "storekey":"TEST1234"}",
"uniqueReferans": "182709220424024254",
"ts": "20190118-14:51:33",
"s": "TKkP/kkIhgtj+2u8CiXRjsCtIuibNVBTQIk/bjMztx09nm0//AKjGRRT2kCjPzC1Yx7QUTRej/cCZE/jTWCrU/8W/jsojbgJO4MLjPOqLyI1B64FOKVeA9u1y+GUT9tN7XJTCTzpOz0OqqKqrTH1YNOKPlwslLfC22KzMB2KfIPCIUS+QFAVaIaGt4qjf4FAK7HcdDfU72eiY21cOuTzUbuQK+hsO5KEQY1B2j++04oeqvgKMkfejGHiM2nl0wcZwzQgJT9AOJvxWspJRVR1fA0gZobyOPrhlYWk48Fj0gTgTiggcdr3yYHyvCXrUHYD3RENY6mIhXF2/v0pFc++QQ=="
}
//Kuştüyü entegrasyon için örnek doReversalWithRef Request İsteği:
{
"merchantId": "2CBB2A88-1768-4565-B052-7DF37738DBCF",
"requestType": "1",
"amount": "12,31",
"currency": "949",
"transactionToken": "78ccd398-6ff6-431c-beeb-f1c9a90a8a14",
"posUid": "",
"posPwd": "",
"extra": "",
"uniqueReferans": "182709220424024254",
"ts": "20190118-14:51:33",
"s": "TKkP/kkIhgtj+2u8CiXRjsCtIuibNVBTQIk/bjMztx09nm0//AKjGRRT2kCjPzC1Yx7QUTRej/cCZE/jTWCrU/8W/jsojbgJO4MLjPOqLyI1B64FOKVeA9u1y+GUT9tN7XJTCTzpOz0OqqKqrTH1YNOKPlwslLfC22KzMB2KfIPCIUS+QFAVaIaGt4qjf4FAK7HcdDfU72eiY21cOuTzUbuQK+hsO5KEQY1B2j++04oeqvgKMkfejGHiM2nl0wcZwzQgJT9AOJvxWspJRVR1fA0gZobyOPrhlYWk48Fj0gTgTiggcdr3yYHyvCXrUHYD3RENY6mIhXF2/v0pFc++QQ=="
}
//Kuştüyü entegrasyon için örnek doReversalWithRef Request İsteği:
{
"merchantId": "2CBB2A88-1768-4565-B052-7DF37738DBCF",
"requestType": "1",
"amount": "12,31",
"currency": "949",
"transactionToken": "78ccd398-6ff6-431c-beeb-f1c9a90a8a14",
"posUid": "",
"posPwd": "",
"extra": "",
"uniqueReferans": "182709220424024254",
"ts": "20190118-14:51:33",
"s": "TKkP/kkIhgtj+2u8CiXRjsCtIuibNVBTQIk/bjMztx09nm0//AKjGRRT2kCjPzC1Yx7QUTRej/cCZE/jTWCrU/8W/jsojbgJO4MLjPOqLyI1B64FOKVeA9u1y+GUT9tN7XJTCTzpOz0OqqKqrTH1YNOKPlwslLfC22KzMB2KfIPCIUS+QFAVaIaGt4qjf4FAK7HcdDfU72eiY21cOuTzUbuQK+hsO5KEQY1B2j++04oeqvgKMkfejGHiM2nl0wcZwzQgJT9AOJvxWspJRVR1fA0gZobyOPrhlYWk48Fj0gTgTiggcdr3yYHyvCXrUHYD3RENY6mIhXF2/v0pFc++QQ=="
}
//Kuştüyü entegrasyon için örnek doReversalWithRef Request İsteği:
{
"merchantId": "2CBB2A88-1768-4565-B052-7DF37738DBCF",
"requestType": "1",
"amount": "12,31",
"currency": "949",
"transactionToken": "78ccd398-6ff6-431c-beeb-f1c9a90a8a14",
"posUid": "",
"posPwd": "",
"extra": "",
"uniqueReferans": "182709220424024254",
"ts": "20190118-14:51:33",
"s": "TKkP/kkIhgtj+2u8CiXRjsCtIuibNVBTQIk/bjMztx09nm0//AKjGRRT2kCjPzC1Yx7QUTRej/cCZE/jTWCrU/8W/jsojbgJO4MLjPOqLyI1B64FOKVeA9u1y+GUT9tN7XJTCTzpOz0OqqKqrTH1YNOKPlwslLfC22KzMB2KfIPCIUS+QFAVaIaGt4qjf4FAK7HcdDfU72eiY21cOuTzUbuQK+hsO5KEQY1B2j++04oeqvgKMkfejGHiM2nl0wcZwzQgJT9AOJvxWspJRVR1fA0gZobyOPrhlYWk48Fj0gTgTiggcdr3yYHyvCXrUHYD3RENY6mIhXF2/v0pFc++QQ=="
}
doReversalWithRef Request “s” alanı için İmza Sıralaması: uniqueReferans , merchantId , requestType , amount , currency , posUid , posPwd , transactionToken, ts
ÖNEMLİ: BKM Express Entegrasyonunuz Kuştüyü alt yapısındaysa posUid ve posPwd alanlarını null gönderebilirsiniz ve null olduğu için imza datanıza eklemeyiniz.Eğer web servis entegrasyonunu kullanıyor iseniz, posUid ve posPwd alanlarını dolu göndermeniz ve imza sıralamasına alanları eklemeniz gerekir.
doReversalWithRef Response Parametreleri
DÖNÜŞ PARAMETRESİ | Tipi |
Zorunlu(m)/ Opsiyonel(o) |
Uzunluk | AÇIKLAMA |
uniqueReferans | String | m | 50 | İşyerinin her işlem için gönderdiği unique referans numarası. |
ts | String | m | 17 | yyyyMMdd-hh:mm:ss formatında |
s | String | m | Tüm alanların tablodaki sırayla concat edilerek “SHA-256 with RSA” ile imzalanmış hali | |
>code | String | m | 3 | Bkz: doReversalWithRef hata kodları tablosu |
>message | String | m | 1024 | Bkz: doReversalWithRef hata kodları tablosu |
PosResult | complex | m | ||
>orderId | String | c | <1024 | Sipariş numarası |
>authCode | String | c | <1024 | Otorizasyon kodu |
>posResponse | String | c | <1024 | APPROVED ya da DECLINED değeri alır. |
>posResultCode | String | c | <1024 | APPROVED ise 00, DECLINED ise bankanın döndüğü hata kodu bulunur. |
>posResultMessage | String | c | <1024 | Bankanın döndüğü hata mesajı bulunur. |
>referansNumber | String | c | <1024 | Sanal POS’tan gelen referans numarası. |
>posTransactionId | String | c | <1024 | Sanal POS’tan gelen transaction ID. |
>groupId | String | c | <1024 | |
>cardBin | String | c | <1024 | İşlem yapılan kart BIN’i. |
>cardBank | String | c | <1024 | İşlem yapılan kart bankasını EFT kodu. |
>noflnst | İnt | c | Taksit sayısı. | |
>posBank | string | c | <1024 | Sanal POS bankasının EFT kodu. |
doReversalWithRef Response “s” alanı için İmza Sıralaması aşağıdaki gibi olmalıdır;
uniqueReferans , PosResult , ts
PosResult parametresininde kendi içinde imza sıralaması var, aşağıdaki gibi olmalıdır;
orderId,authCode,posResponse,posResultCode,posResultMessage,referansNumber, posTransactionId,groupId,cardBin,cardBank,noflnst,posBank
doReversalWithRef Hata Kodları
resCode | resMsg |
0 | Success |
1 | System Error |
2 | Invalid Input Parameters |
3 | Time Synchronization Error |
4 | MAC verification Failed |
5 | Undefined merchant id |
6 | NonUnique Reference Id |
7 | Virtual Pos Error |
8 | Invalid Acquirer Bank ID |
9 | Invalid Transaction Token |
5. BIN Servisi
İşyerinin E-Ticaret Bin Listesini alabileceği rest servistir.
getBinList Preprod Endpoint Adresi:
https://preprod.bkmexpress.com.tr/BKMExpress/service/bin/getEightBinList.do
getBinList Production Endpoint Adresi:
https://www.bkmexpress.com.tr/BKMExpress/service/bin/getEightBinList.do
//getBinList örnek istek
{
"uniqueRefNo": "64e7a855-7e2a-46fa-ac17-5becc42f1449",
"merchantId": "size iletilen merchantid",
"sign": "uniqueRefNomerchantId şifrelenmiş hali"
}
//getBinList örnek istek
{
"uniqueRefNo": "64e7a855-7e2a-46fa-ac17-5becc42f1449",
"merchantId": "size iletilen merchantid",
"sign": "uniqueRefNomerchantId şifrelenmiş hali"
}
//getBinList örnek istek
{
"uniqueRefNo": "64e7a855-7e2a-46fa-ac17-5becc42f1449",
"merchantId": "size iletilen merchantid",
"sign": "uniqueRefNomerchantId şifrelenmiş hali"
}
getBinList Request Parametreleri
İSTEK PARAMETRESİ | Tipi |
Zorunlu(m)/ Opsiyonel(o) |
Uzunluk | AÇIKLAMA |
uniqueRefNo | String | m | max 64 | İşyerinin her sorgulama işlemi için göndereceği unique referans numarası. |
merchantId | String | m | 32 | İşyerinin tanımlı merchant id’si. |
sign | String | m | Yukarıdaki alanların tablodaki sırayla concat edilerek “SHA-256 with RSA” ile imzalanmış hali(uniqrefnomerchantid) |
getBinList Request İmza sıralaması : uniqueRefNo, merchantId
getBinList Response Parametreleri
DÖNÜŞ PARAMETRESİ | Tipi |
Zorunlu(m)/ Opsiyonel(o) |
Uzunluk | AÇIKLAMA |
resultCode | int | m | Dönüş kodu. (bkz. Dönüş Kodları) 0: Başarılı Diğer değerler: Hata kodu içerir. (Bkz hata kodları) |
|
resultMsg | String | m | <1024 | Dönüş mesajı. (bkz. Dönüş Kodları) |
uniqueRefNo | String | m | 64 | İşyeri her sorgulama işlemi için göndereceği unique referans numarası. |
sign | String | m | Yukarıdaki alanların tablodaki sırayla concat edilerek “SHA-256 with RSA” ile imzalanmış hali. (İmza sıralamasına aşağıdaki alanlar dahil değildir) | |
> cardType | String | m | Kart tipi debit or credit | |
> isBusinessCard | String | m | Kart tipi | |
>memberName | String | m | Banka adı | |
>memberNo | long | m | Banka kodu | |
>rangeStart | String | m | Range başlangıcı | |
>rangeEnd | String | m | Range bitişi |
getBinList Response imza sıralaması : resultCode, resultMsg , uniqueRefNo
getBinList Hata Kodları
resCode | resMsg |
0 | Success |
1 | System Error(loglar incelenmeli) |
2 | MAC verification Failed |
3 | Invalid Input Parameters |
6. Flow QR Servisi
BKM Express Flow 2.0 entgrasyonumuz üzerinden size dönülen ticket token id'yi QR'a çevirerek ödeme işlemi alabilirsiniz.
6.1 QR Oluşturma Servisi (getEmvQrForLogin) :
https://test-api.bkmexpress.com.tr/docs/ sayfasında yer alan entagrasyon adımlarının tümünün tamamlanmış olması gerekmektedir.Aşağıdaki adımlar ise QR entegrasyonunu kullanabilmeniz için yapmanız gereken değişikliklerdir.
• “Bex.init” metodunda size dönülen ticket token id bilgisi ile aşağıdaki servise istek göndererek, QR data bilgisine ulaşabilirsiniz.
• QR datayı kullanacağınız QR generator tool üzerinden QR formatına çevirebilirsiniz.
• Sayfanızda oluşturduğunuz QR’ı BKM Express uygulaması ile okuttuğunuzda kullanıcı BKM Express uygulamasında kart seçim sayfasına yönlenecektir. Bu adımda backend tarafında geliştirdiğiniz installment adresinize ulaşacaktır.
• BKM Express uygulamasında kullanıcı kartını seçip OTP bilgisini girerek ödeme işlemini tamamlar. Bu adımda ödeme işlemi tamamlanmadan önce backend tarafında geliştirdiğiniz nonce adresinize ulaşacaktır.Nonce’dan ok cevabınız sonrası merchantnonceresponse’u çağırarak ilgili posdan ödeme işlemi tamamlanır ve ödeme sonucu NonceResultResponse ‘a dönülür.
QR Oluşturma Endpoint URL: (Test Ortam)
https://test-api.bkmexpress.com.tr/v1/user/getEmvQrForLogin
// Örnek QR oluşturma için gönderilen istek:
{"merchantId": "219be6b5-e3cd-4ad1-9843-a16340a0bfe2",
"token": "076c22d7-7a2f-42a2-85b8-8e1e873de730"}
// Örnek QR oluşturmada dönülen cevap:
{
"code": "OK-FE-CON-001",
"call": "user/getEmvQrForLogin",
"description": "Başarılı bağlantı.",
"message": "getEmvQrForLogin called.",
"result": "ok",
"parameters": {},
"data": "0002010102122690000400FF01230000000000000000000000002122019100107250312816585513180040480000501106011070142746000403400720012345678901234567890905TDVMA1001N5204000053039495802TR590060011"
}
//data = EmvQrText
getEmvQrForLogin Request Parametreleri
İSTEK PARAMETRESİ | Tipi |
Zorunlu(m)/ Opsiyonel(o) |
Uzunluk | AÇIKLAMA |
merchantId | String | m | 36 | İşyerinin tanımlı merchant id’si. |
token | String | m | <1024 | BEX.init aşamasında dönülen ticket token id değeri yazılır. |
getEmvQrForLogin Response Parametreleri
Cevap İçeriği | |
---|---|
code alanı |
Bu alan içerisinde istek sonuç kodu döner.Hata kodları için tıklayın. |
call alanı |
Çağırılan servisin adı |
description alanı |
Açıklama |
message alanı |
Dönülen Mesaj |
result alanı |
Açıklama |
paramaters alanı |
Parametre |
data alanı |
EMV formatında QR data içeriği |
6.2 QR Sorgualama Servisi (queryQrStatus) :
Kullanıcınız QR'ı BKM Express uygulaması üzerinden okuttuğunda mobilden işlemine devam ederken , QR'ın statüsüne göre sayfanızda Loading mesajı gösterebilirsiniz. QR ‘ın statüsünü öğrenmek için ise aşağıdaki servisi kullanabilirsiniz. Dönülen statüye göre ilgili sayfanıza redirect edebilirsiniz.
QR Sorgulama Endpoint URL: (Test Ortam)
https://test-api.bkmexpress.com.tr/v1/user/queryQrStatus
// Örnek QR statü sorgulama için gönderilen istek:
{"token": "4d5a6506-2eb7-4ecd-8ff9-6c65b69f40bb"}
// Örnek QR statü sorgulama için dönülen response:
{
"code": "OK-FE-CON-001",
"call": "user/queryQrStatus",
"description": "Başarılı bağlantı.",
"message": "queryQrStatus called.",
"result": "ok",
"parameters": {},
"data": {
"status": "C",
"resultCode": 0,
"resultMsg": "Success"
}
}
// Status: C:Created, R:Read , F:Fail, S:Success
queryQrStatus Request Parametreleri
İSTEK PARAMETRESİ | Tipi |
Zorunlu(m)/ Opsiyonel(o) |
Uzunluk | AÇIKLAMA |
token | String | m | <1024 | getEmvQrForLogin servisine ilettiğiniz token değeri yazılır. |
queryQrStatus Response Parametreleri
Cevap İçeriği | |
---|---|
code alanı |
Bu alan içerisinde istek sonuç kodu döner.Hata kodları için tıklayın. |
call alanı |
Çağırılan servisin adı |
description alanı |
Açıklama |
message alanı |
Dönülen Mesaj |
result alanı |
Açıklama |
paramaters alanı |
Parametre |
data alanı |
data içeriği tablosundaki değerler dönülür |
data İçeriği | |
---|---|
status alanı |
QR'ın statüsü |
resultCode alanı |
Cevap Kodu |
resultMsg alanı |
Dönülen Mesaj |
Statüler:
C (Created): Sayfanızda QR oluştu.
R (Read) : Sayfanızda QR Okundu.
F (Fail) : Sayfanızda QR iptal edildi veya ödeme işlemi başarılı tamamlanamadı.
S (Success) : Sayfanızda QR ile ödeme işlemi başarılı tamamlandı.
6.3 QR Ödeme İşlemi Sorgulama:
QR ödeme işlemin durumunu sorgulamak için işlem sorgulama servisini kullanabilirsiniz.İşlem sorgulama servisini kullanmak için tıklayın.
6.4 QR İptal / İade Servisi:
QR ile BKM Express üzerinden gerçekleşen işlemin sanal pos İptal / İade 'sini sağlayabilirsiniz.İptal/İade servisini kullanmak için tıklayın.