├── screen-1.png ├── screen-2.png ├── screen-mob.png ├── README.md └── yourtempalte ├── css └── invoice.css └── viewinvoice.tpl /screen-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shionphan/whmcs-invoice-tpl/HEAD/screen-1.png -------------------------------------------------------------------------------- /screen-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shionphan/whmcs-invoice-tpl/HEAD/screen-2.png -------------------------------------------------------------------------------- /screen-mob.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shionphan/whmcs-invoice-tpl/HEAD/screen-mob.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | WHMCS invoice template 2 | === 3 | 4 | The invoice template in WHMCS is too ugly. 5 | 6 | ## USAGE 7 | 8 | * Replace the file `viewinvoice.tpl` in your template folder; 9 | * To ensure that the CSS file `invoice.css` reference path is correct; 10 | * ** Base on bootstrap style **; 11 | * Compatible with WHMCS6 and WHMCS7, because of Invoice template is relatively simple, if you want to be compatible with WHMCS5, you should only need to modify some main variables; 12 | 13 | Enjoy! 14 | 15 | ## DEMO 16 | 17 | ![scree-3.png](screen-mob.png) 18 | 19 | ![scree-1.png](screen-1.png) 20 | 21 | ![scree-2.png](screen-2.png) 22 | 23 | ## License 24 | 25 | The MIT License (MIT) -------------------------------------------------------------------------------- /yourtempalte/css/invoice.css: -------------------------------------------------------------------------------- 1 | /** 2 | @author https://github.com/shionphan 3 | */ 4 | .inv-cont{ 5 | max-width: 928px; 6 | background: #fff; 7 | border-radius: 3px; 8 | border: 1px dotted #ccc; 9 | margin: 1em auto; 10 | padding: 1.5em; 11 | } 12 | .inv-cont h1{ 13 | margin:0 0 20px; 14 | } 15 | .inv-paystatus{ 16 | padding: 5px 10px; 17 | color:#fff; 18 | font-size: 20px; 19 | margin-bottom: 10px; 20 | border-radius: 3px; 21 | } 22 | .inv-payment{ 23 | margin:10px auto; 24 | } 25 | .inv-paymathod{ 26 | border: 1px solid #ddd; 27 | margin-top: 10px; 28 | border-radius: 3px; 29 | padding: 10px; 30 | } 31 | @media(min-width:768px){ 32 | .inv-paymathod{ 33 | min-height: 260px; 34 | } 35 | } 36 | .inv-paymathod p{ 37 | font-size: 16px; 38 | text-align: left; 39 | } 40 | .inv-invnum{ 41 | background-color: #ffffff; 42 | border-bottom: 1px dashed #ddd; 43 | } 44 | .inv-paymon{ 45 | font-size: 28px; 46 | color:#2e962c; 47 | } 48 | h2{ 49 | margin:10px auto; 50 | font-size: 18px; 51 | font-weight: bold; 52 | } 53 | .panel{ 54 | border-radius: 0; 55 | } 56 | .panel h2{ 57 | margin:0; 58 | } 59 | .panel .panel-heading{ 60 | border-radius: 0; 61 | } 62 | .inv-company{ 63 | border-bottom: 1px dashed #ddd; 64 | } 65 | .draft { 66 | background-color: #888; 67 | color:#333; 68 | } 69 | .unpaid { 70 | background-color: #cc0000; 71 | } 72 | .paid { 73 | background-color: #779500; 74 | } 75 | .refunded { 76 | background-color: #224488; 77 | } 78 | .cancelled { 79 | background-color: #888; 80 | color:#333; 81 | } 82 | .collections { 83 | background-color: #8a6d03; 84 | } -------------------------------------------------------------------------------- /yourtempalte/viewinvoice.tpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | {$companyname} - {* This code should be uncommented for EU companies using the sequential invoice numbering so that when unpaid it is shown as a proforma invoice {if $status eq "Paid"}*}{$LANG.invoicenumber}{*{else}{$LANG.proformainvoicenumber}{/if}*}{$invoicenum} 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | {if $error} 18 |
{$LANG.invoiceserror}
19 | {else} 20 |
21 |
22 |
23 |

{if $logo}

{else}

{$companyname}

{/if} 24 |
25 |
26 |
27 |

{$LANG.firstpaymentamount}

28 |

{$total}

29 |
30 |
31 |

{* This code should be uncommented for EU companies using the sequential invoice numbering so that when unpaid it is shown as a proforma invoice {if $status eq "Paid"}*}{$LANG.invoicenumber}{*{else}{$LANG.proformainvoicenumber}{/if}*}{$invoicenum}

32 |

{$LANG.invoicesdatecreated}: {$datecreated}
{$LANG.invoicesdatedue}: {$datedue}

33 |
34 |
35 |
36 |
37 |

{$LANG.invoicespayto}

38 |

{$payto}

39 |
40 |
41 |

{$LANG.invoicesinvoicedto}

42 |

43 | {if $clientsdetails.companyname}{$clientsdetails.companyname}
{/if} 44 | {$clientsdetails.firstname} {$clientsdetails.lastname}
45 | {$clientsdetails.address1}, {$clientsdetails.address2}
46 | {$clientsdetails.country} {$clientsdetails.state} {$clientsdetails.city} {$clientsdetails.postcode} 47 | {if $customfields} 48 | {foreach from=$customfields item=customfield} 49 | {$customfield.fieldname}: {$customfield.value}
50 | {/foreach} 51 | {/if} 52 |

53 |
54 |
55 |
56 |
57 | {if $status eq "Unpaid"} 58 |
{$LANG.invoicesunpaid}
59 | {if $allowchangegateway} 60 |
{$gatewaydropdown}
61 | {else} 62 |
{$paymentmethod}
63 | {/if} 64 |
{$paymentbutton}
65 | {elseif $status eq "Paid"} 66 | 67 |
{$paymentmethod}
68 |

({$datepaid})

69 | {elseif $status eq "Refunded"} 70 |
{$LANG.invoicesrefunded}
71 | {elseif $status eq "Cancelled"} 72 |
{$LANG.invoicescancelled}
73 | {elseif $status eq "Collections"} 74 |
{$LANG.invoicescollections}
75 | {/if} 76 | 77 | {if $smarty.get.paymentsuccess} 78 | 79 | {elseif $smarty.get.pendingreview} 80 | 81 | {elseif $smarty.get.paymentfailed} 82 |
{$LANG.invoicepaymentfailedconfirmation}
83 | {elseif $offlinepaid} 84 |
{$LANG.invoiceofflinepaid}
85 | {/if} 86 | 87 | {if $manualapplycredit} 88 |
89 | 90 |
91 | {$LANG.invoiceaddcreditdesc1} {$totalcredit}. {$LANG.invoiceaddcreditdesc2}
92 | {$LANG.invoiceaddcreditamount}: 93 |
94 |
95 | {/if} 96 |
97 |
98 |
99 |
100 |
101 |

{$LANG.invoicestransamount}

102 |
103 |
104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | {foreach from=$invoiceitems item=item} 113 | 114 | 115 | 116 | 117 | {/foreach} 118 | 119 | 120 | 121 | 122 | {if $taxrate} 123 | 124 | 125 | 126 | 127 | {/if} 128 | {if $taxrate2} 129 | 130 | 131 | 132 | 133 | {/if} 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 |
{$LANG.invoicesdescription}{$LANG.invoicesamount}
{$item.description}{if $item.taxed eq "true"} *{/if}{$item.amount}
{$LANG.invoicessubtotal}:{$subtotal}
{$taxrate}% {$taxname}:{$tax}
{$taxrate2}% {$taxname2}:{$tax2}
{$LANG.invoicescredit}:{$credit}
{$LANG.invoicestotal}:{$total}
144 |
145 | {if $taxrate} 146 |
147 | * {$LANG.invoicestaxindicator} 148 |
149 | {/if} 150 |
151 |

{$LANG.invoicestransactions}

152 |
153 |
154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | {foreach from=$transactions item=transaction} 165 | 166 | 167 | 168 | 169 | 170 | 171 | {foreachelse} 172 | 173 | 174 | 175 | {/foreach} 176 | 177 | 178 | 179 | 180 | 181 |
{$LANG.invoicestransdate}{$LANG.invoicestransgateway}{$LANG.invoicestransid}{$LANG.invoicestransamount}
{$transaction.date}{$transaction.gateway}{$transaction.transid}{$transaction.amount}
{$LANG.invoicestransnonefound}
{$LANG.invoicesbalance}:{$balance}
182 |
183 | {if $notes} 184 |
185 | {$LANG.invoicesnotes}: {$notes} 186 |
187 | {/if} 188 |
189 | 190 |
191 | {/if} 192 |
193 | 194 | --------------------------------------------------------------------------------