CanPay
Angular component for accepting payments in CAN through a seamless user experience using an a configurable params, See how does it work.
Overview
Accepting payment with token in any dApp can be cumbersome because a developer needs to do mulitple checks and transactions in order to finalize a payment and same applies for the CanYaCoin (CAN).
To streamline the process, we've created a component that takes care of the following:
- Check for the installed user wallet (Metamask or Trust)
- Guide the user to install or unlock the wallet
- Check the user CAN balance
- Allow a user to buy CAN or ETH (for gas) if he doesn't have enough balance
- Paying in CAN in a dApp, requires 2 transactions:
- First, user has to authorise a payment from his address to the dApp address
- Second, the dApp needs to withdraw the authorised funds and complete the user operation.
- Allow a user to buy CAN's if he doesn't have enough .
- Allow a user to buy CAN's with ETH or supported ERC20 token.
- Before poping up Metamask dialog to the user to execute a transaction, the wizard explains the transaction purpose and what's going to happen.
- After authorising a payment, the wizard calles (optionally) configured callback so the developer can do the authorised payment through his dApp contract.
- A callback is triggered upon successful completion for the whole operation
- Lastly, the component is configurable so it can be embedded inline or used as popup modal dialog.
Usage
Component is packed in an npm package and can be used as normal angular module.
Installation
In your module file:
import { CanpayModule } from 'canpay-lib';
@NgModule({
declarations: [
AppComponent,
],
imports: [
BrowserModule,
CanpayModule.forRoot({
useTestNet: <TRUE_FALSE>,
contracts: {
canyaCoinAddress: <CanYaCoin_ADDRESS>,
canyaAbi: <CanYaCoin_ABI>
}
})
],
providers: [],
bootstrap: [AppComponent],
})
Using as Inline-Component
canPay = {
dAppName: 'CANWork',
recipient: <CANWORK_CONTRACT_ADDRESS>,
amount: <AMOUNT_IN_CAN>,
complete: <CALLBACK_ON_SUCCESS>,
cancel: <CALLBACK_ON_CANCEL>
}
<canyalib-canpay
[dAppName]="canPay.dAppName"
[successText]="canPay.successText"
[recipient]="canPay.recipient"
[amount]="canPay.amount"
(complete)="canPay.complete($event)"
(cancel)="canPay.cancel($event)"
></canyalib-canpay>
Nothing to be defiend in the template file, only in the controller file.
canPay = {
dAppName: 'CANWork',
recipient: <CANWORK_CONTRACT_ADDRESS>,
amount: <AMOUNT_IN_CAN>,
complete: <CALLBACK_ON_SUCCESS>,
cancel: <CALLBACK_ON_CANCEL>
}
constructor(private canPayService: CanPayService) { }
open() {
this.canPayService.open(this.canPay);
}
onCancel(){
this.canPayService.close();
}
Component Configuration
Here is a list of the full list of peroperties to configure the CANPay component.
Property | Description |
---|
dAppName | Name of the dApp to be displayed to the user as a merchant name. |
onAuthTxHash | Function to execute once the hash of the transaction is returned from the authorisation operation. |
recipient | The dApp contract address that will receive the payment |
amount | Optional If set, no amount-input-box will be displayed to the user and the specified amount will be forced. |
paymentSummary | Optional If set, will show a nice payment summary screen of the transaction, if not set, uses amount. |
minAmount | Optional If amount is set, this will be the minum accepted amount from the user. |
maxAmount | Optional If amount is set, this will be the maximum accepted amount from the user. |
complete | Callback to be triggered upon successful completion of the whole wizard steps. Input: CanPayData |
cancel | Callback to be triggered if the user cancelled the wizard. Input: CanPayData |
postAuthorisationProcessName | Optional Action name to be exexuted after payment authorisation, Ex: 'Task Deposit'. |
startPostAuthorisationProcess | Optional callback to be triggered after a user authorisation for the requested amount. It's used to allow a developer to execute external/extended payment operation from the CanYaCoin contract to the dApp contract. Input: CanPayData |
postAuthorisationProcessResults | Optional if postAuthorisationProcessName is set. It's used to notify the wizard of the success or failure of the postAuthorisationProcess. |
destinationAddress | It is the destination address of the user where the CANS will be transferred. |
disableCanEx | Should CanExchange be enabled for the purchasing of CAN (default true) |
userEmail | Email address to send canexchange verification email |
Interfaces
CANPay
interface CanPay {
dAppName: string;
operation?: Operation;
onAuthTxHash? : Function;
recipient: string;
amount?: number;
paymentSummary?: PaymentSummary;
minAmount?: number;
maxAmount?: number;
postAuthorisationProcessName?: string;
postAuthorisationProcessResults?: ProcessActionResult;
canyaContract?: Contract;
startPostAuthorisationProcess?: Function;
complete: Function;
cancel?: Function;
currentStep?: Function;
disableCanEx? : boolean;
destinationAddress?: string;
userEmail?: string;
}
Wizard Steps
The following are the enum for full wizard steps:
enum Step {
metamask = 0,
paymentAmount = 1,
balanceCheck = 2,
buyCan = 3,
authorisation = 4,
payment = 5,
process = 6,
confirmation = 7,
completed = 8,
details = 9,
staging = 10,
erc20 = 11,
complete = 12,
qr = 13,
error = 14
}
Operation
Type of CanPay operations, default is Authorise.
enum Operation {
auth = 'Authorise',
pay = 'Pay'
interact = 'Interact'
}
ProcessActionResult
A message to notify CANPay with the postAuthorisationProcess execution results.
interface ProcessActionResult {
type: ProcessAction;
msg: string;
}
CanPayData
Data passed to the callback functions (complete, cancel and startPostAuthorisationProcess)
Property | Description |
---|
amount | Amount specified by either the developer or entered by the user |
account | User eth address |
balance | User CAN balance |
step | Current wizard Step |
View
Customize the wizard UI to fit in small areas
enum View {
Normal,
Compact
}
Helpers
setProcessResult
A utility function that sets the postAuthorisationProcessResults
based on the passed in transaction param. See usage example
function setProcessResult(txOrErr) {
this.postAuthorisationProcessResults = {
type: !txOrErr.status ? ProcessAction.error : ProcessAction.success,
msg: !txOrErr.status ? (txOrErr.message || 'Transaction failed') : null
};
}
Complete Example
The CanPayExample is a fully working example on how to use the CanPay with postAuthorisationProcess params.
Running the Example App
- Run
git clone git@github.com:canyaio/Common.git && cd Common && git checkout lib/canpay && npm i
- Start your local test net 'truffle' instance by running
ganache-cli --port 9545
- From main project directory, deploy CanYaCoin and Dao contracts to your testnet by running
npm run init-deploy-contracts
- Update environment vars with the deployed contract addresses, you will find the addresses in the file
zos.local.json
under ./src/
directory - Update global vars with appropriate staging address.
- Run
npm run build_lib && npm start
- Open your browser at http://localhost:4200
- Done!