Let $C$ be the price of the option, $S_t=S_0e^{X_t}$ be the stock price, $r$ be the risk-free rate, $K$ be the strike price, $T$ be the maturity time, $m=S_0/K$, $f$ be the density of $X_T$ and $\phi$ be the characteristic function $E(e^{i\xi X_T})$ which we assume is known.
$$
C = e^{-rT}E((S_T-K)^+) = e^{-rT}S_0\int_{-\infty}^\infty \left(e^x-m\right)\mathbb{I}_{\{x>\ln(m)\}}f(x)dx \\
= e^{-rT}S_0\int_{-\infty}^\infty e^{-ax}\left(e^{ax}\left (e^x-m\right)\mathbb{I}_{\{x>\ln(m)\}}\right)f(x)dx.
$$
We exponentially damp the payoff is order to ensure its Fourier transform exists. Then we re-write the last in terms of the inverse Fourier transform of the Fourier transform of the damped payoff. Note that the damped payoff is integrable so long as $a<-1$.
Now the Fourier transform of the damped payoff is
$$ \mathcal{F}\left(e^{ax}\left (e^x-\frac{K}{S_0}\right)\mathbb{I}_{\{x>m\}}\right):=h(\xi) = \frac{m^{1+a+i\xi}}{(a+i\xi)(1+a+i\xi)} $$
which then allows
$$
C = e^{-rT}S_0\int_{-\infty}^{\infty}e^{-ax}\left( \frac{1}{2\pi}\int_{-\infty}^{\infty} h(\xi)e^{-ix\xi}d\xi \right) f(x)dx \\
= e^{-rT}S_0 Re\left( \int_{-\infty}^{\infty}e^{-ax}\left( \frac{1}{\pi}\int_{0}^{\infty} h(\xi)e^{-ix\xi}d\xi \right) f(x)dx \right) \\
= \frac{e^{-rT}S_0}{\pi}Re\left( \int_{0}^{\infty} \left( \int_{-\infty}^{\infty}f(x)e^{i(ia-\xi)x}dx \right)h(\xi)d\xi \right) \\
= \frac{e^{-rT}S_0}{\pi}S_0\ Re \left( \int_{0}^{\infty} \phi(ia-\xi)h(\xi)d\xi \right).
$$
The second step here is justified because the damped payoff is real. Hence $h$ is even in its real part and odd in its imaginary part. The third step requires Fubini's theorem which holds in most cases of interest.
This expression can be used immediately to price a single option or allows discretisation in a form compatible with the FFT. If you use the FFT with $N$ discretisation points the output will be $N$ option prices calculated for $N$ levels of $m$ (which may be useful for calibration).
See Pascucci (2011) PDE and martingale methods in option pricing (chapter 15) for more details and for a newer method using cosine expansions.
P.S. I have added an image of some simple Mathematica code for the GBM case.
