mcard.vn

Giới thiệu MCard API

MCard API cung cấp các hàm để lập trình cho đối tác giao tiếp MCard
## Mô tả

MCard API (mcapi) cung cấp các hàm để lập trình hệ thống giao tiếp MCard, truyền và
nhận thông tin qua Internet bên cạnh giao tiếp Web thông thường. Tất cả API mặc định
xây dựng theo kiểu REST (Representation State Transfer) qua HTTP.

Các API cung cấp được thiết kế theo cách đơn giản nhất, dữ liệu định dạng kiểu JSON,
thích hợp client viết bằng bất kỳ ngôn ngữ nào (PHP, Java, Python hay JavaScript...).

Hệ thống có thể cung cấp khả năng xử lý hàng trăm lệnh mỗi giây, độ trễ thấp (<100ms),
liên tục cập nhât và được bảo mật bởi tiêu chuẩn công nghiệp thông dụng.

## Xác thực & bảo mật

### Xác thực

Các API sử dụng cơ chế xác thực thông qua kiểm tra chuỗi API Key được gửi trong
HTTP Request và địa chỉ IP nguồn gửi đến.

API Key là chuỗi ký tự (hexa) có độ dài tối đa 96 ký tự (bỏ qua space), được sinh
ngẫu nhiên gắn với mỗi đại lý, khi đại ký đăng ký tại trang Server API. Mỗi đại lý
chỉ có duy nhất 1 API Key cho S2Sell ở một thời điểm, và có thể tắt đi nếu cần.

Chuỗi API Key được gửi kèm HTTP Request qua 2 cách:

1. Đặt trong HTTP header với trường có tên `"X-API-Key: APIKeyString"`
2. Đặt trong query string (kể cả HTTP POST) với dạng: `"/path?...&api_key=APIKeyString"`

Đồng thời, hệ thống cũng sẽ kiểm tra nguồn IP (public) gửi tới, đối chiếu danh sách
các địa chỉ cho phép mà đại lý thiết lập tại trang Server API. Sau khi thiết lập
hệ thống chỉ cho phép các request tới từ địa chỉ được định nghĩa trước. Để đảm bảo an
toàn thì trường này luôn luôn được định nghĩa và nên đặt vừa đủ các địa chỉ truy cập.

Việc quản lý truy cập API (của từng đại lý) được đặt trong trang
[Server API](https://mcard.vn/mcard/api_server) của
màn hình MCard Web sau khi đăng nhập.

### Bảo mật

Mọi lời gọi API đều được kết nối thông qua HTTPS tới máy chủ MCard chính thức theo
URL sau đây (base-URL):

```
https://mcard.vn/mcapi
```

_(Riêng môi trường test được cung cấp riêng, xin xem ở dưới)_

Do sử dụng HTTPS, nên mọi mã hoá được đảm bảo bởi giao thức này (yêu cầu tối
thiểu TLSv1.0, hỗ trợ độ dài khoá 2048 bit).

MCard luôn sử dụng chứng chỉ số được chứng thực công cộng theo tiêu chuẩn mà trình
duyệt web thông dụng chấp nhận. Do đó Quý đại lý cần lưu ý khi lập trình bắt tay
SSL cần bật kiểm tra tên hostname và chứng chỉ số hợp lệ ký bởi CA Cert trong trust
store của hệ thống (Linux, Windows, Java). **KHÔNG** bypass kiểm tra này bởi nó sẽ
ảnh hưởng đến tính chất bảo mật của kênh truyền. Các thư viện hỗ trợ HTTPS/SSL đều
mặc định kiểm tra.

Ngoài ra _nên_ bật tuỳ chọn kiểm tra chứng chỉ có bị revoke hay không qua OCSP/CRL.
Nếu bật, thư viện SSL sử dụng bắt tay kết nối lúc này cần truy vấn đến web site
của các nhà cung cấp chứng chỉ số thế giới như Verisign, Microsoft, Goddady... Có
thể hơi chậm hơn nên cache lại, và nếu không kết nối được sẽ thấy truy vấn rất chậm.

## Gửi yêu cầu, phân tích kết quả & bắt lỗi HTTP.

### HTTP Request

API hỗ trợ giao thức HTTP/1.0 hoặc HTTP/1.1, hoạt động qua SSL (HTTPS) hoặc không theo
đúng tiêu chuẩn mà trình duyệt sử dụng. Tuy nhiên có 1 số lưu ý sau:

#### Với phương thức GET

Dữ liệu gửi lên có thể chứa tham số, được chứa trong query string
theo định dạng: `key=value[&key=value...]`

Phương thức GET thường được dùng với các hàm truy vấn thông tin, và một số trường hợp
thông tin có thể cache lại tại client hoặc HTTP Proxy trung gian.

#### Với phương thức POST/PUT/PATCH

Dữ liệu gửi lên trong nội dung request. Trong đó request header phải chứa 2 trường:

* **"Content-Type"**, hỗ trợ phân tích 2 định dạng: `application/json` (dạng JSON `{"key":"value",...}`)
hoặc `application/x-www-form-urlencoded` theo định dạng: `key=value[&key=value...]`
* **"Content-Length"**: độ dài nội dung gửi lên, không quá 2 Megabytes.

_Lưu ý:_ khi xác thực bằng cách gửi api_key theo query string, POST cũng vẫn yêu cầu
api_key nằm trên query string dạng "/path?api_key=xxx". Hệ thống sẽ không đọc
API Key trong body của request.

#### Với phương thức khác

Các phương thức khác không yêu cầu dữ liệu gửi lên, cũng không yêu cầu query_string
(trừ api_key, nếu có)

### HTTP Response & Error

Trừ trường hợp lỗi hoặc sai Resource URI, MCard luôn trả về Response với body content
dưới dạng dữ liệu kiểu JSON. Các thông tin khác trong response header gồm có:

* **"Content-Type: application/json; charset=utf-8"** luôn có
* **"Content-Length"** độ dài của content
* **"Cache-control: no-cache"** trong trường hợp dữ liệu không được cache.
* **"Last-Modified"** ngày tháng sửa đổi của dữ liệu, chỉ cho HTTP GET, giúp cho
dữ liệu có cache được. Client có thể gửi request với header này và có thể nhận được
HTTP Status Code 304 nghĩa là resource chưa bị thay đổi kể từ lần lấy cuối cùng.

Khi OK hoặc có lỗi, API sẽ trả về giá trị HTTP Status Code theo đúng ý nghĩa của chuẩn. Các code
thường thấy như sau:

* **200 OK**: lệnh thành công, có dữ liệu kèm theo
* **204 No content**: lệnh thành công nhưng không có dữ liệu kèm theo.
* `400 Bad request`: lỗi lệnh gửi lên bất hợp lệ cú pháp
* `403 Forbiden`: không xác thực đúng, hoặc bị từ chối truy cập.
* `404 Not found`: không tồn tại resource hoặc dữ liệu cần truy vấn.
* `405 Method Not Allowed`: sai phương thức
* `411 Length Required`: phải có content-length header >0 ở request gửi lên
* `413 Payload Too Large`: dữ liệu quá lớn
* `429 Too Many Requests`: gửi quá nhiều request (lỗi)
* `500 Internal Server Error`: lỗi của API Server
* `503 Service Unavailable`: hệ thống tạm ngưng phục vụ (vì lỗi hoặc bảo trì).
* `504 Gateway Timeout`: hệ thống bị quá tải

### JSON Error Object

Trong trường hợp API trả về JSON Object (gốc), thì object gốc này phải có chứa "error"
object mô tả lỗi theo cấu trúc sau:

```
{"error":{"message":"error message here","code":-1}}
```

Trong đó:

* **"error"**: object mô tả lỗi, nếu có object này trong kết quả là có lỗi.
* **"code"**: mã lỗi.
* **"message"**: thông tin mô tả lỗi (nếu có).

Danh sách mã lỗi code (thường thấy) như sau:

* -1 => 'HTTP Error - lỗi giao thức HTTP',
* -2 => 'Invalid input data format or data length - dữ liệu đàu vào sai khuôn dạng hoặc kích thước',
* -3 => 'The action not allowed - hành động không cho phép',
* -4 => 'Card type is not valid or disabled - loại thẻ không hợp lệ nữa',
* -5 => 'Card series is not valid or not sold - mã series thẻ không hợp lệ hoặc không cho phép bán',
* -9 => 'Our application/database error - lỗi ứng dụng có kiểm soát của chúng tôi',
* -10 => 'No API Key - chưa có mã xác thực',
* -11 => 'API Key is invalid format (hexa string) - mã xác thực sai khuôn dạng, phải là chuỗi hexa',
* -12 => 'API Key is not found - mã xác thực không tìm thấy trong CSDL',
* -13 => 'API Key is not active - mã xác thực không còn hiệu lực',
* -14 => 'API Key is not valid for the API service - mã xác thực không dành cho dịch vụ API này',
* -15 => 'API Key is allowed from the source address - không cho phép truy cập từ địa chỉ này với mã xác thực đó',
* -16 => 'Too many API ID, not any more - đã tạo quá nhiều mã xác thực',
* -17 => 'API Session is invalid - phiên làm việc API bất hợp lệ',
* -18 => 'Unique ID or REFID duplicate and violation  - mã REFID bị trùng hoặc mã xác định tính duy nhất bị vi phạm',
* -201 => Hết thẻ trong kho thẻ
* -202 => Hết tiền

### Thư viện hỗ trợ

REST API Client được hỗ trợ rộng rãi với các thư viện sau (gợi ý sử dụng):

* PHP: [Guzzle PHP](https://github.com/guzzle/guzzle)
* Java: [Apache HttpClient](http://hc.apache.org/httpclient-3.x/)
* .Net: [Windows Communication Foundation](https://msdn.microsoft.com/en-us/library/dd456779.aspx)