Skip to content

Commit e91bcea

Browse files
Readme v1.2.0 Repo folder name: android-mobile-sdk
1 parent 13f5966 commit e91bcea

9 files changed

+379
-0
lines changed

README.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Table of contents
2+
3+
- [Table of contents](#table-of-contents)
4+
- [PostFinance Checkout Android Payment SDK](#postfinance-checkout-android-payment-sdk)
5+
- [Installation](#installation)
6+
- [Requirements](#requirements)
7+
- [Configuration](#configuration)
8+
- [Documentation](#documentation)
9+
10+
# PostFinance Checkout Android Payment SDK
11+
12+
[![Maven Central](https://img.shields.io/maven-central/v/ch.postfinance/postfinance-checkout-sdk)](https://central.sonatype.com/artifact/ch.postfinance/postfinance-checkout-sdk/1.2.0)
13+
14+
## Installation
15+
16+
### Requirements
17+
18+
- Android 7.0 (API level 24) and above
19+
20+
### Configuration
21+
22+
Add `postfinance-checkout-sdk` to your `app/build.gradle` dependencies.
23+
24+
```groovy
25+
dependencies {
26+
// ...
27+
implementation("ch.postfinance:postfinance-checkout-sdk:1.2.0")
28+
// ...
29+
}
30+
```
31+
32+
## Documentation
33+
34+
- [API Reference](./docs/api-reference.md)
35+
- [Integration](./docs/integration.md)
36+
- [Theming](./docs/theming.md)

docs/api-reference.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
## API reference
2+
3+
| API | Type | Description |
4+
| --- | :-: | --- |
5+
| `PostFinanceCheckoutSdk.init(listener: OnResultEventListener)` | constructor | Initialization of SDK. Both Parameters are required! |
6+
| `OnResultEventListener` | interface | Interface for handling post-payment events `paymentResult` |
7+
| `fun paymentResult(paymentResult: PaymentResult)` | function | Result handler for transaction state |
8+
| `PostFinanceCheckoutSdk.instance?.launch(token: String)` | function | Opening payment dialog (activity) |
9+
| `PostFinanceCheckoutSdk.instance?.setDarkTheme(theme: JSONObject)` | function | Can override the whole dark theme or just some specific color. All colors are in json format |
10+
| `PostFinanceCheckoutSdk.instance?.setLightTheme(theme: JSONObject)` | function | Can override the whole light theme or just some specific color. All colors are in json format |
11+
| `PostFinanceCheckoutSdk.instance?.setCustomTheme(theme: JSONObject?, baseTheme: ThemeEnum)` | function | Force to use only this theme (independent on user's setup). Can override default light/dark theme and force to use it or completely replace all or specific colors |
12+
| `PostFinanceCheckoutSdk.instance?.setAnimation(type: AnimationEnum)` | function | Defining type of animation for moving between the pages |

docs/integration.md

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
## Integration
2+
3+
- [Integration](#integration)
4+
- [Set up PostFinance Checkout](#set-up-postfinance-checkout)
5+
- [Create transaction](#create-transaction)
6+
- [Collect payment details](#collect-payment-details)
7+
- [Handle result](#handle-result)
8+
- [Verify payment](#verify-payment)
9+
10+
### Set up PostFinance Checkout
11+
12+
To use the Android Payment SDK, you need a [PostFinance Checkout account](https://checkout.postfinance.ch/user/signup). After signing up, set up your space and enable the payment methods you would like to support.
13+
14+
### Create transaction
15+
16+
For security reasons, your app cannot create transactions and fetch access tokens. This has to be done on your server by talking to the [PostFinance Checkout Web Service API](https://checkout.postfinance.ch/en-us/doc/api/web-service). You can use one of the official SDK libraries to make these calls.
17+
18+
To use the Android Payment SDK to collect payments, an endpoint needs to be added on your server that creates a transaction by calling the [create transaction](https://checkout.postfinance.ch/doc/api/web-service#transaction-service--create) API endpoint. A transaction holds information about the customer and the line items and tracks charge attempts and the payment state.
19+
20+
Once the transaction has been created, your endpoint can fetch an access token by calling the [create transaction credentials](https://checkout.postfinance.ch/doc/api/web-service#transaction-service--create-transaction-credentials) API endpoint. The access token is returned and passed to the Android Payment SDK.
21+
22+
```bash
23+
# Create a transaction
24+
curl 'https://checkout.postfinance.ch/api/transaction/create?spaceId=1' \
25+
-X "POST" \
26+
-d "{{TRANSACTION_DATA}}"
27+
28+
# Fetch an access token for the created transaction
29+
curl 'https://checkout.postfinance.ch/api/transaction/createTransactionCredentials?spaceId={{SPACE_ID}}&id={{TRANSACTION_ID}}' \
30+
-X 'POST'
31+
```
32+
33+
### Collect payment details
34+
35+
Before launching the Android Payment SDK to collect the payment, your checkout page should show the total amount, the products that are being purchased and a checkout button to start the payment process.
36+
37+
Is recommended to initialize `PostFinanceCheckoutSdk` in `Application` class. You can always access `PostFinanceCheckoutSdk` instance and `paymentResult` from everywhere in your app.
38+
39+
```kotlin
40+
// ...
41+
import android.app.Application
42+
import ch.postfinance.PostFinanceCheckoutSdk
43+
import ch.postfinance.event.OnResultEventListener
44+
import ch.postfinance.event.PaymentResult
45+
46+
class MyApp : Application() {
47+
48+
private val _mainState = MutableLiveData<PaymentResult>()
49+
val mainState: LiveData<PaymentResult> get() = _mainState
50+
51+
override fun onCreate() {
52+
super.onCreate()
53+
PostFinanceCheckoutSdk.init(listener = object : OnResultEventListener{
54+
override fun paymentResult(paymentResult: PaymentResult) {
55+
_mainState.postValue(paymentResult)
56+
}
57+
})
58+
}
59+
//...
60+
}
61+
```
62+
63+
When the customer taps the checkout button, call your endpoint that creates the transaction and returns the access token, and launch the payment dialog.
64+
65+
```kotlin
66+
// ...
67+
68+
class MainActivity : AppCompatActivity() {
69+
lateinit var btnCheckout: Button
70+
71+
var token = "" // to get token you have to create transaction. Checkout previous section #Create transaction
72+
73+
override fun onCreate(savedInstanceState: Bundle?) {
74+
super.onCreate(savedInstanceState)
75+
setContentView(R.layout.activity_main)
76+
77+
btnCheckout.setOnClickListener {
78+
PostFinanceCheckoutSdk.instance?.launch(token, this) ?: run {
79+
Log.e(
80+
"Mobile SDK",
81+
"SDK is not initialized. Did you forget to run init on Application?"
82+
)
83+
}
84+
}
85+
86+
}
87+
88+
// ...
89+
}
90+
```
91+
92+
After the customer completes the payment, the dialog dismisses and the `paymentResult` method is called.
93+
94+
### Handle result
95+
96+
The response object contains these properties:
97+
98+
- `code` describing the result's type.
99+
100+
| Code | Description |
101+
| --- | --- |
102+
| `COMPLETED` | The payment was successful. |
103+
| `FAILED` | The payment failed. Check the `message` for more information. |
104+
| `CANCELED` | The customer canceled the payment. |
105+
| `PENDING` | The customer has aborted the payment process, so the payment is in a temporarily pending state. It will eventually reach a final status (successful or failed), but it may take a while. Wait for a webhook notification and use the PostFinance Checkout API to retrieve the status of the transaction and inform the customer that the payment is pending. |
106+
| `TIMEOUT` | Token for this transaction expired. App will be closed and third-party app will get this message. For opening payment sdk third party app have to refetch token |
107+
108+
- `message` providing a localized error message that can be shown to the customer.
109+
110+
```kotlin
111+
112+
class MainActivity : AppCompatActivity() {
113+
// ...
114+
lateinit var txtResultMessage: TextView
115+
116+
117+
override fun onCreate(savedInstanceState: Bundle?) {
118+
//...
119+
txtResultMessage = findViewById(R.id.txtResultMessage)
120+
121+
init()
122+
}
123+
124+
private fun init() {
125+
(application as? MyApp)?.mainState?.observe(this) { paymentResult ->
126+
127+
txtResultMessage.text = paymentResult.code.toString()
128+
val colorCodeMap = mapOf(
129+
PaymentResultEnum.FAILED to Color.RED,
130+
PaymentResultEnum.COMPLETED to Color.GREEN,
131+
PaymentResultEnum.CANCELED to Color.parseColor("#ffa500")
132+
)
133+
colorCodeMap[paymentResult.code]?.let { it1 -> txtResultMessage.setTextColor(it1) }
134+
}
135+
}
136+
137+
// ...
138+
}
139+
140+
141+
```
142+
143+
### Verify payment
144+
145+
As customers could quit the app or lose network connection before the result is handled or malicious clients could manipulate the response, it is strongly recommended to set up your server to listen for webhook events the get transactions' actual states. Find more information in the [webhook documentation](https://checkout.postfinance.ch/en-us/doc/webhooks).

docs/theming.md

Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
## Theming
2+
3+
- [Theming](#theming)
4+
- [Colors](#colors)
5+
- [Animation](#animation)
6+
- [Default themes](#default-themes)
7+
- [Light theme](#light-theme)
8+
- [Dark theme](#dark-theme)
9+
10+
The appearance of the payment dialog can be customized to match the look and feel of your app. This can be done for both the light and dark theme individually.
11+
12+
Colors can be modified by passing a JSON object to the `PostFinanceCheckoutSdk` instance. You can either completely override the theme or only change certain colors.
13+
14+
- `PostFinanceCheckoutSdk.instance?.setLightTheme(JSONObject)` allows to modify the payment dialog's light theme.
15+
- `PostFinanceCheckoutSdk.instance?.setDarkTheme(JSONObject)` allows to modify the payment dialog's dark theme.
16+
- `PostFinanceCheckoutSdk.instance?.setCustomTheme(JSONObject, ThemeEnum)` allows to enforce a specific theme (dark, light or your own).
17+
18+
```kotlin
19+
// ...
20+
import ch.postfinance.enums.ThemeEnum
21+
22+
class MainActivity : AppCompatActivity() {
23+
// ...
24+
25+
override fun onCreate(savedInstanceState: Bundle?) {
26+
super.onCreate(savedInstanceState)
27+
setContentView(R.layout.activity_main)
28+
29+
PostFinanceCheckoutSdk.instance?.setDarkTheme(getCustomTheme())
30+
PostFinanceCheckoutSdk.instance?.setLightTheme(getCustomTheme())
31+
}
32+
33+
fun getCustomTheme(): JSONObject {
34+
val customTheme = JSONObject()
35+
customTheme.put("colorBackground", "#ABA2A2")
36+
customTheme.put("colorText", "#2F4858")
37+
customTheme.put("colorHeadingText", "#4F5769")
38+
customTheme.put("colorError", "#998D91")
39+
return customTheme
40+
}
41+
42+
// ...
43+
}
44+
```
45+
46+
This will override the colors `colorBackground`, `colorText`, `colorHeadingText` and `colorError` for both the dark and light theme.
47+
48+
The `setCustomTheme` function allows to define the theme to be used by the payment dialog and prevent it from switching themes based on the user's settings. This way e.g. high- and low-contrast themes can be added. The logic for switching between these themes is up to you though.
49+
50+
```kotlin
51+
// ...
52+
import ch.postfinance.enums.ThemeEnum
53+
54+
class MainActivity : AppCompatActivity() {
55+
// ...
56+
57+
override fun onCreate(savedInstanceState: Bundle?) {
58+
super.onCreate(savedInstanceState)
59+
setContentView(R.layout.activity_main)
60+
61+
PostFinanceCheckoutSdk.instance?.setCustomTheme(getCustomTheme(), ThemeEnum.DARK)
62+
}
63+
64+
fun getCustomTheme(): JSONObject {
65+
val customTheme = JSONObject()
66+
customTheme.put("colorBackground", "#0800FC")
67+
customTheme.put("colorText", "#EA00B6")
68+
customTheme.put("colorHeadingText", "#FF0071")
69+
customTheme.put("colorError", "#FF693E")
70+
return customTheme
71+
}
72+
73+
//...
74+
}
75+
```
76+
77+
You can also use `setCustomTheme` to force the usage of the light or dark theme.
78+
79+
```kotlin
80+
//...
81+
PostFinanceCheckoutSdk.instance?.setCustomTheme(null, ThemeEnum.DARK)
82+
```
83+
84+
### Colors
85+
86+
![Payment method list](../imgs/theme-1.jpeg) ![Payment method details](../imgs/theme-2.jpeg) ![Pyament method additional details](../imgs/theme-3.jpeg)
87+
88+
### Animation
89+
90+
Use `setAnimation` method to change the screen change animation. Currently avaliable options are: `AnimationEnum.SLIDE` and `AnimationEnum.BUBBLE`. Default value is `AnimationEnum.SLIDE`. `PostFinanceCheckoutSdk.instance?.setAnimation(AnimationEnum.BUBBLE)` allows to modify the payment dialog's dark theme. ![Slide Animation](../imgs/slideAnimation.gif) ![Bubble Animation](../imgs/bubbleAnimation.gif)
91+
92+
### Default themes
93+
94+
#### Light theme
95+
96+
```json
97+
{
98+
"colorPrimary": "#3b82f6",
99+
"colorBackground": "#ffffff",
100+
"colorText": "#374151",
101+
"colorSecondaryText": "#6b7280",
102+
"colorHeadingText": "#111827",
103+
"colorError": "#ef4444",
104+
"toast": {
105+
"border": "#F14D00",
106+
"background": "#FFF6F6",
107+
"messageText": "#ef4444"
108+
},
109+
"component": {
110+
"colorBackground": "#ffffff",
111+
"colorBorder": "#d1d5db",
112+
"colorText": "#374151",
113+
"colorPlaceholderText": "#4b5563",
114+
"colorFocus": "#3b82f6",
115+
"colorSelectedText": "#1e3a8a",
116+
"colorSelectedBackground": "#eff6ff",
117+
"colorSelectedBorder": "#bfdbfe",
118+
"colorDisabledBackground": "#80808019"
119+
},
120+
"buttonPrimary": {
121+
"colorBackground": "#2563eb",
122+
"colorText": "#ffffff",
123+
"colorHover": "#1d4ed8"
124+
},
125+
"buttonSecondary": {
126+
"colorBackground": "#bfdbfe",
127+
"colorText": "#1d4ed8",
128+
"colorHover": "#bfdbfe"
129+
},
130+
"buttonText": {
131+
"colorText": "#6b7280",
132+
"colorHover": "#374151"
133+
},
134+
"buttonIcon": {
135+
"colorText": "#9ca3af",
136+
"colorHover": "#6b7280"
137+
}
138+
}
139+
```
140+
141+
#### Dark theme
142+
143+
```json
144+
{
145+
"colorPrimary": "#3b82f6",
146+
"colorBackground": "#1f2937",
147+
"colorText": "#e5e7eb",
148+
"colorSecondaryText": "#9ca3af",
149+
"colorHeadingText": "#f9fafb",
150+
"colorError": "#ef4444",
151+
"toast": {
152+
"border": "#F14D00",
153+
"background": "#222222",
154+
"messageText": "#ef4444"
155+
},
156+
"component": {
157+
"colorBackground": "#374151",
158+
"colorBorder": "#6b7280",
159+
"colorText": "#f3f4f6",
160+
"colorPlaceholderText": "#9ca3af",
161+
"colorFocus": "#3b82f6",
162+
"colorSelectedText": "#f3f4f6",
163+
"colorSelectedBackground": "#4b5563",
164+
"colorSelectedBorder": "#9ca3af",
165+
"colorDisabledBackground": "#9ca3af"
166+
},
167+
"buttonPrimary": {
168+
"colorBackground": "#2563eb",
169+
"colorText": "#ffffff",
170+
"colorHover": "#1d4ed8"
171+
},
172+
"buttonSecondary": {
173+
"colorBackground": "#6b7280",
174+
"colorText": "#f3f4f6",
175+
"colorHover": "#4b5563"
176+
},
177+
"buttonText": {
178+
"colorText": "#9ca3af",
179+
"colorHover": "#d1d5db"
180+
},
181+
"buttonIcon": {
182+
"colorText": "#d1d5db",
183+
"colorHover": "#f3f4f6"
184+
}
185+
}
186+
```

imgs/bubbleAnimation.gif

485 KB
Loading

imgs/slideAnimation.gif

455 KB
Loading

imgs/theme-1.jpeg

32 KB
Loading

imgs/theme-2.jpeg

49 KB
Loading

imgs/theme-3.jpeg

50.3 KB
Loading

0 commit comments

Comments
 (0)