# HTML formları

Bir siteye, çevrimiçi mağazaya veya bota kripto ödemeleri eklemenin yollarından biri. Alıcı bir düğmeye tıklar ve faturanın bulunduğu ödeme sayfası açılır.

Form yalnızca POST ile `https://dash.bitsby.app/invoices/form` adresine gönderilir ve iki alan içerir:

| Alan | İçeriği |
| --- | --- |
| `data` | Fatura alanlarını içeren JSON'un base64url'si |
| `signature` | `data` dizesinin HMAC-SHA256'sı, 64 hex karakter |

Bir projede bu yolla oluşturulmuş en fazla 50 ödenmemiş fatura aynı anda bulunabilir.

## Form örneği

```html
<form method="post" action="https://dash.bitsby.app/invoices/form" target="_blank">
    <input type="hidden" name="data" value="eyJwcm9qZWN0SWQiOiJhMWIyYzNkNC01ZTZm...">
    <input type="hidden" name="signature" value="f77d6da1be35bd2900e0bfed9f202b04...">
    <button type="submit">Pay</button>
</form>
```

Mağazanın sunucusu, sayfayı oluştururken her iki değeri de doldurur. Gizli anahtar hiçbir zaman işaretlemede görünmez.

`target="_blank"` özniteliği isteğe bağlıdır: bu öznitelikle sepet, ilk sekmede açık kalır.

## Kap nasıl oluşturulur

1. Fatura alanlarını içeren bir JSON nesnesi oluşturun.
2. Bunu base64url olarak kodlayın. Bu, `data` dizesidir.
3. `signature = HMAC-SHA256(data, formSecret)` değerini hesaplayın.

`data` dizesi bütün olarak imzalanır; bu yüzden JSON anahtarlarının sırası, girintileme ve Unicode kaçış stili önemli değildir. Hizmet, dolgulu veya dolgusuz standart base64'ü de kabul eder.

İmzaladıktan sonra `data` değerini yeniden oluşturmayın: tek bir bayt bile değişirse imzanın yeniden hesaplanması gerekir.

İmzanın nasıl hesaplanacağı, dört dilde hazır örneklerle birlikte [HTML formu imzası](./form-signature.md) sayfasında ele alınır.

## data içindeki anahtarlar

| Anahtar | Zorunlu | İçeriği |
| --- | --- | --- |
| `projectId` | evet | Paneldeki ayarlarda bulunan proje ID'si, uuid |
| `amountFiat` | evet | 1 ile 100.000 arasında tutar, en fazla iki ondalık basamak. `"10.50"` dizesi veya `10.5` sayısı olarak |
| `currencyFiat` | evet | İtibari para birimi: USD, EUR veya RUB |
| `timeToPay` | evet | Saat cinsinden ödeme süresi: 0.5, 1, 3, 6, 12. Dize veya sayı olarak |
| `description` | hayır | Alıcı için açıklama, en fazla 1.000 karakter |
| `serviceData` | hayır | Mağaza tarafındaki sipariş tanımlayıcısı, en fazla 1.000 karakter. Alıcıya gösterilmez ama formun kaynak kodunda görünür — buraya hassas hiçbir şey koymayın |
| `output` | hayır | `errors` — doğrulama hatalarının ayrıntılarını göster |

İsteğe bağlı bir anahtar JSON'dan çıkarılabilir — bu, boş dizeyle aynıdır. Anahtarlar herhangi bir sırada olabilir; hizmet bilinmeyen anahtarları yok sayar.

Değerler JSON dizeleri veya sayılardır. Boole değerleri, diziler ve iç içe nesneler alan değeri sayılmaz ve boş dize olarak gelir.

`data` içeriği örneği:

```json
{
    "projectId": "a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
    "amountFiat": 10.5,
    "currencyFiat": "USD",
    "timeToPay": 1,
    "description": "Order #7, delivery",
    "serviceData": "order-7"
}
```

Burada tutar ve ödeme süresi sayı olarak gönderilmiştir; dizeler de kabul edilir. İsteğe bağlı `output` hiç ayarlanmamıştır.

## Tutar biçimi

Yalnızca rakamlar ve ondalık nokta, en fazla iki ondalık basamak: `10`, `10.00`, `1000.50`. Baştaki ve sondaki boşluklar kırpılır.

Diğer tüm biçimler reddedilir — binlik ayırıcılar, nokta yerine virgül, üstel gösterim, sayının önünde işaret, para birimi simgesi. Yuvarlama yoktur: üçüncü ondalık basamak kesilmez, reddedilmeye yol açar.

## Form gizli anahtarı

Gizli anahtar, paneldeki proje ayarlarında, Form gizli anahtarı (Form secret) alanında bulunur. Sunucu bunu proje oluşturulduğunda verir. Kendi değerinizi ayarlayamazsınız; gizli anahtar yalnızca yeniden verilebilir — örneğin ele geçirilirse.

Gizli anahtar, mağazanın sunucusunda kalmalıdır. Vitrin HTML'sine sızarsa imza anlamsız hale gelir.

Form gizli anahtarı ile webhook gizli anahtarı farklı anahtarlardır; bunları karıştırmayın.

## Sipariş tanımlayıcısı

`serviceData` alanını her zaman doldurun: oraya kendi sipariş tanımlayıcınızı koyun. Değer, [ödeme bildiriminde](../../webhook-url/index.md) geri gelir — mağaza, siparişi bununla bulur.

Doldurulmuş bir `serviceData`, kopyalara karşı korur. Formun yeniden gönderilmesi veya düğmeye çift tıklanması ikinci bir fatura oluşturmaz: alıcı, mevcut ödenmemiş faturaya yönlendirilir. Eşleştirme, sipariş alanlarına göre yapılır — proje, tutar, para birimi, açıklama ve `serviceData` — `data` baytlarına göre değil.

Değer, her sipariş için benzersiz olmalıdır. Aynı değerle ikinci bir alıcı, ilk alıcının ödenmemiş faturasına düşer.

Boş bir `serviceData` bu korumayı kaldırır: tekrarı tanıyacak bir şey kalmaz ve her gönderim yeni bir fatura oluşturur. Kopyalar, 50 ödenmemiş fatura limitini tüketir; biri ödendiğinde ise mağazanın ödemeyi bir siparişe bağlayacak hiçbir şeyi olmaz.

## Hatalar ve hata ayıklama modu

Form iki kontrolden geçer: önce imza ve kap, ardından alan değerleri.

| Ne oldu | Hizmet ne gösterir |
| --- | --- |
| İmza eşleşmiyor, kap okunamıyor, proje başkasına ait veya mevcut değil | Genel bir hata, neden belirtilmez |
| İmza eşleşiyor ama bir alan yanlış doldurulmuş | Genel bir hata. `"output":"errors"` ile — ayrıntılı hatalar |
| Her iki kontrol de geçti | Faturanın bulunduğu ödeme sayfası |

İlk kontrol, hiçbir ayarda nedeni açıklamaz.

JSON'daki `"output":"errors"` çifti, ikinci kontrol için ayrıntıları etkinleştirir: hizmet alanı adlandırır, izin verilen değerleri listeler ve 50 ödenmemiş fatura tavanına ulaşıldığını bildirir. Anahtar, imzalı kabın içindedir; bu yüzden dışarıdan enjekte edilemez.

Formu kurarken JSON'a `"output":"errors"` koyun; kurulum bittikten sonra anahtarı kaldırın ve kabı yeniden oluşturun.

İmzanın kendisi eşleşmiyorsa `data` ve imzanızı [HTML formu imzası](./form-signature.md) sayfasındaki referans setiyle karşılaştırın.

## Sırada ne var

Formla oluşturulan bir fatura, API'den veya panelden gelenle aynı şekilde işlenir:

* **Ödeme onayı** [Webhook URL](../../webhook-url/index.md) adresine gelir. [Bildirim imzasını](../../webhook-url/signature-verification.md) webhook gizli anahtarıyla doğrulayın ve siparişleri yalnızca buna dayanarak teslim edin.
* **Alıcıyı sitenize döndürme**, Successful URL ve Unsuccessful URL ile yapılandırılır — [Fatura yaşam döngüsü](../../invoice-lifecycle.md) sayfasındaki “Alıcıyı mağaza sitesine döndürme” bölümüne bakın. Bu adreslere gelinmesi ödemeyi onaylamaz.
* **Fatura durumları ve ödeme arama penceresi** [Fatura yaşam döngüsü](../../invoice-lifecycle.md) sayfasında anlatılır.
* **Alıcı yanlış tutar gönderdi** — bkz. [Ödeme eşleştirme ve tutar uyuşmazlıkları](../../payment-matching.md).
